如何获得当前正在执行的代码的HMODULE?

我有一个静态库,可能会链接到.exe.dll 。 在运行时,我想要使用我的库函数来获取HMODULE ,无论静态库代码已经链接到什么地方。

我目前使用下面的技巧(从这个论坛的启发):

 const HMODULE GetCurrentModule() { MEMORY_BASIC_INFORMATION mbi = {0}; ::VirtualQuery( GetCurrentModule, &mbi, sizeof(mbi) ); return reinterpret_cast<HMODULE>(mbi.AllocationBase); } 

有没有更好的方法来做到这一点,看起来不那么hacky?

(注意:这样做的目的是加载一些Win32资源,我知道我的用户将同时链接到我的静态库。)

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

__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

我会使用GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS标志来查看GetModuleHandleEx() 。 它看起来像你可以改变你的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; } 

我没有尝试,但我认为这将做你想要的。

HMODULE是HINSTANCE是模块的基地址。 所以,我会看看它是如何工作的。 但是,如果你想要的只是可执行文件的HMODULE,为什么不枚举过程中的所有HMODULE(EnumProcessModules)。 其中之一将链接你的.lib。

我看到的限制是你不知道你的.lib来自哪个DLL或EXE。 您可能需要将HMODULE(基本地址)与您从.lib获得的_ReturnAddress进行比较。 您的.lib将属于比您的_ReturnAddress更小的最高HMODLUE