天天看點

[Windows程式設計] 通過GetModuleHandleEx 得到函數調用者所在的DLL/EXE

在有些情況下需要得到函數調用者的子產品名字。比如你想限制你的某個函數隻能被自己某個特定的DLL調用。 或者比如在異常進行中你想了解是那個DLL/EXE抛出了異常。

API函數_ReturnAddress 和GetModuleHandleEx 函數可以幫助我們達到這個目的。以下代碼示範它們的用法:

 view plaincopy to clipboardprint?

void ShowCallerModuleName()   

{   

    HMODULE hCallerModule = NULL;   

    TCHAR szModuleName[MAX_PATH] = _T("");   

    void *callerAddress = _ReturnAddress();   

    if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)callerAddress, &hCallerModule))   

    {   

        GetModuleFileName(hCallerModule, szModuleName, ARRAYSIZE(szModuleName));   

        MessageBox(NULL, szModuleName, _T("Who is calling me?"), MB_OK);   

    }   

}  

void ShowCallerModuleName()

{

 HMODULE hCallerModule = NULL;

    TCHAR szModuleName[MAX_PATH] = _T("");

 void *callerAddress = _ReturnAddress();

    if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)callerAddress, &hCallerModule))

 {

  GetModuleFileName(hCallerModule, szModuleName, ARRAYSIZE(szModuleName));

  MessageBox(NULL, szModuleName, _T("Who is calling me?"), MB_OK);

 }

}

解釋:

_ReturnAddress 可以給你所在函數的傳回位址,也就是調用者的位址。

GetModuleHandleEx 可以給你某個位址所在的子產品Handle 。 得到這個Handle 之後,就可以用GetModuleFileName 來得到子產品的檔案名了。

如上面提到的,我們可以用這個方法來捕捉是哪個DLL/EXE抛出異常。 在程式入口加入

view plaincopy to clipboardprint?

SetUnhandledExceptionFilter(ShowCallerModuleName); 

 本文轉自 陳本峰 51CTO部落格,原文連結:http://blog.51cto.com/wingeek/273935,如需轉載請自行聯系原作者

繼續閱讀