上一篇介绍了DIA的基础信息以及几个重要的接口。这章讲详细介绍这些接口的详细使用和成员函数。
接口使用方式
DIA SDK的接口使用方式和很多COM对象不太一样,为了方便使用,一旦创建得到了接口IDiaDataSource就不需要再通过QueryInterface来获得其他的DIA SDK的功能接口了。取而代之的是openXXX,get_XXX,findXXX之类的成员函数,可以直接得到作为输出参数的接口指针成员。
Enumeration
因为DIA通常的使用方式是作为获得symbol里面的信息。因此最常用的就是枚举操作。DIA为枚举操作设计了接口IDiaEnumSymbols。其中最重要的方法就是Next。
HRESULT Next (
IN ULONG celt, // 希望获得的Symbol数量
OUT IDiaSymbol** rgelt, // 存放Symbol的数组
OUT ULONG* pceltFetched // 获取到的Symbol的数量
);
伪代码如下
while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt))
{
...
}
IDiaEnumSymbols接口由IDiaSymbol得到。其中最基础的方法为findChildren。
HRESULT findChildren (
IN enum SymTagEnum symtag, // 指定需要获得哪种类型的symbol
IN LPCOLESTR name, // 获得指定名称的symbol
IN DWORD compareFlags, // 指定name来匹配的选项,例如大小写之类的。
OUT IDiaEnumSymbols** ppResult
);
Symbol Information
从FindChildren函数的第一个参数可以看到可以从pdb文件中获得各种不同的symbol信息。
这里简单列部分我写的程序里面所列举出来的部分symbol信息类型。
- Module 其对象为链接的对象,例如dll,obj等,而且包含有路径。几乎所有的详细信息都可以认为是Module的子对象。
- Compile 包含有该对象的编译时的信息。例如编译选项,编译命令,原始文件名及路径等,
- Namespace 里面会列出其中使用到的名称空间名称。
- Function 函数里面包含的信息也是很多的,其中包含除了函数签名相关信息,也会有编译之后的偏移信息,更重要的是和源文件的mapping信息。
Summary
DIA SDK 本身强大而且使用简单。希望能够帮大家更好的理解PDB里面的构造信息。