如何获得当前正在执行的代码的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)。 从这里你可以把它的地址投给HINSTANCE
或HMODULE
。 所以比通过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