2009-02-17 95 views
31

我有一個靜態庫,可能會鏈接到.exe.dll。在運行時,我希望我的庫函數能夠獲得HMODULE的靜態庫代碼已鏈接到的任何東西。如何獲取當前正在執行的代碼的HMODULE?

我目前使用下面的技巧(從this forum啓發):

const HMODULE GetCurrentModule() 
{ 
    MEMORY_BASIC_INFORMATION mbi = {0}; 
    ::VirtualQuery(GetCurrentModule, &mbi, sizeof(mbi)); 

    return reinterpret_cast<HMODULE>(mbi.AllocationBase); 
} 

是否有更好的方法可以做到這一點看起來不那麼哈克?

(注:這樣做的目的是加載,我知道我的用戶將在同一時間,我的靜態庫已發現,在一些Win32的資源。)

+0

相關:http://stackoverflow.com/q/119706/946850 – krlmlr 2012-02-21 02:59:59

回答

42
HMODULE GetCurrentModule() 
{ // NB: XP+ solution! 
    HMODULE hModule = NULL; 
    GetModuleHandleEx(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, 
    (LPCTSTR)GetCurrentModule, 
    &hModule); 

    return hModule; 
} 
+0

很酷。我現在記得,當我編寫GetCurrentModule()函數時,我們必須支持Windows 2000.這就是爲什麼我使用VirtualQuery()hack而不是GetModuleHandleEx()。 – pauldoo 2009-02-18 08:57:54

+0

GLad幫忙。出於好奇,你爲什麼喜歡我的解決方案在__ImageBase之一? – 2009-02-18 14:23:07

3

我想看看GetModuleHandleEx()使用標記GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS。看起來您可以更改您的GetCurrentModule()以調用此例程而不是VirtualQuery(),並將GetCurrentModule()的地址作爲lpModuleName參數傳遞。

ETA:

const HMODULE GetCurrentModule() 
{ 
    DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS; 
    HMODULE hm = 0; 
    ::GetModuleHandleEx(flags, reinterpret_cast<LPCTSTR>(GetCurrentModule), &hm); 
    return hm; 
} 

我沒有嘗試,但我認爲這會做你想要什麼。

-4

HMODULE是HINSTANCE是模塊的基地址。所以,我會看看它是如何工作的。但是如果你想要的只是可執行文件的HMODULE,爲什麼不枚舉過程中的所有HMODULE(EnumProcessModules)。其中之一將鏈接您的.lib。

我看到的限制是您不知道您的.lib來自哪個DLL或EXE。您可能需要將HMODULE(基址)與您從.lib獲得的_ReturnAddress進行比較。您的.lib將屬於最高HMODLUE小於你的_ReturnAddress

+0

枚舉模塊的列表是非常低效的,並幾乎不像調用GetModuleHandleEx那麼簡單。讓我們來看看;通過一個快速的API調用獲得我需要的答案,或者通過潛在的幾十個模塊循環,隨時進行字符串比較(非常昂貴!)。我想我會走捷徑。 – 2016-11-28 05:47:43

25

__ImageBase是一個連接器生成的符號是模塊的DOS頭(只MSVC)。您可以將其地址轉換爲HINSTANCEHMODULE。所以比通過API更方便。

所以,你只需要做到這一點:

EXTERN_C IMAGE_DOS_HEADER __ImageBase; 
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) 

http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx

相關問題