呼叫 DbgHelp 連結庫

雖然DbgHelp.dll隨附於所有版本的 Windows,但呼叫端應考慮使用此 DLL 的其中一個較新版本,如適用於 Windows 的偵錯工具套件中找到。 如需 DbgHelp 散發的詳細資訊,請參閱 DbgHelp 版本

使用 DbgHelp 時,最佳策略是從應用程式目錄中的偵錯工具 For 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 類似的程式代碼。

DbgHelp 版本

LoadLibrary

GetProcAddress

GetModuleFileName