调用 DbgHelp 库
尽管 DbgHelp.dll 随附所有版本的 Windows 提供,但调用方应考虑使用此 DLL 的最新版本之一,如 Windows 调试工具包中所示。 有关 DbgHelp 分发的详细信息,请参阅 DbgHelp 版本。
使用 DbgHelp 时,最佳策略是从应用程序目录中的 Windows 调试工具包安装库的副本,该副本在逻辑上与调用它的软件相邻。 如果需要符号服务器和源服务器,则必须将 SymSrv.dll 和 SrcSrv.dll 都安装在与 DbgHelp.dll 相同的目录中,因为 DbgHelp 仅在与其共享同一目录时才会调用这些 DLL。 (请注意,DbgHelp 不会从标准搜索路径调用这两个 DLL。)这有助于防止使用不匹配的 DLL;同样,它还提高了整体安全性。
以下代码是从 DbgHelp 源中提取的。 它演示了 DbgHelp 如何仅从 DbgHelp.dll 所在的同一目录中加载 SymSrv.dll 和 SrcSrv.dll 的版本。
HINSTANCE ghinst;
// For calculating the size of arrays for safe string functions.
#ifndef cch
#define ccht(Array, EltType) (sizeof(Array) / sizeof(EltType))
#define cch(Array) ccht(Array, (Array)[0])
#endif
//
// LoadLibrary() a DLL, using the same directory as dbghelp.dll.
//
HMODULE
LoadDLL(
__in PCWSTR filename
)
{
WCHAR drive[10] = L"";
WCHAR dir[MAX_PATH + 1] = L"";
WCHAR file[MAX_PATH + 1] = L"";
WCHAR ext[MAX_PATH + 1] = L"";
WCHAR path[MAX_PATH + 1] = L"";
HMODULE hm;
// Chop up 'filename' into its elements.
_wsplitpath_s(filename, drive, cch(drive), dir, cch(dir), file, cch(file), ext, cch(ext));
// If 'filename' contains no path information, then get the path to our module and
// use it to create a fully qualified path to the module we are loading. Then load it.
if (!*drive && !*dir)
{
// ghinst is the HINSTANCE of this module, initialized in DllMain or WinMain
if (GetModuleFileNameW(ghinst, path, MAX_PATH))
{
_wsplitpath_s(path, drive, cch(drive), dir, cch(dir), NULL, 0, NULL, 0);
if (*drive || *dir)
{
swprintf_s(path, cch(path), L"%s%s%s%s", drive, dir, file, ext);
hm = LoadLibrary(path);
if (hm)
return hm;
}
}
}
else
{
// If we wanted to, we could have LoadDLL also support directories being specified
// in 'filename'. We could pass the path here. The result is if no path is specified,
// the module path is used as above, otherwise the path in 'filename' is specified.
// But the standard search logic of LoadLibrary is still avoided.
/*
hm = LoadLibrary(path);
if (hm)
return hm;
*/
}
return 0;
}
加载这两个 DLL 后,DbgHelp 会调用 GetProcAddress 来获取所需的函数。
通常,调用 DbgHelp.dll 的代码会在启动当前进程的应用程序所在的同一目录中安装 DbgHelp.dll,以确保加载正确的版本。 如果调用代码位于 DLL 中,并且无权访问或无法了解初始进程的位置,则 DbgHelp.dll 必须与调用 DLL 一起安装,并且应使用类似于 DbgHelp LoadDLL 的代码。
相关主题