How do I get the HMODULE for the currently executing code?
我有一个静态库,可以链接到
我目前正在使用以下技巧(此论坛启发):
1 2 3 4 5 6 7 | const HMODULE GetCurrentModule() { MEMORY_BASIC_INFORMATION mbi = {0}; ::VirtualQuery( GetCurrentModule, &mbi, sizeof(mbi) ); return reinterpret_cast<HMODULE>(mbi.AllocationBase); } |
有没有更好的方法来做到这一点,看起来似乎不太hacky?
(注意:此操作的目的是加载一些Win32资源,这些资源我知道我的用户将在我的静态库的同时进行链接。)
1 2 3 4 5 6 7 8 9 10 | HMODULE GetCurrentModule() { // NB: XP+ solution! HMODULE hModule = NULL; GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)GetCurrentModule, &hModule); return hModule; } |
因此您只需要执行以下操作:
1 2 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) |
来自https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
我将使用标志
ETA:
1 2 3 4 5 6 7 | const HMODULE GetCurrentModule() { DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS; HMODULE hm = 0; ::GetModuleHandleEx( flags, reinterpret_cast<LPCTSTR>( GetCurrentModule ), &hm ); return hm; } |
我没有尝试过,但是我认为可以做您想要的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #if _MSC_VER >= 1300 // for VC 7.0 #ifndef _delayimp_h extern"C" IMAGE_DOS_HEADER __ImageBase; #endif #endif ... HMODULE module() { #if _MSC_VER < 1300 // earlier than .NET compiler (VC 6.0) MEMORY_BASIC_INFORMATION mbi; static int address; ;::VirtualQuery(&address, &mbi, sizeof(mbi)); return reinterpret_cast(mbi.AllocationBase); #else // VC 7.0 // from ATL 7.0 sources return reinterpret_cast(&__ImageBase); #endif } |
更多在这里https://www.apriorit.com/dev-blog/74-hmodule-hinstance-handle-from-static-library-in-c
HMODULE是HINSTANCE是模块的基地址。因此,我将看看它是如何工作的。但是,如果您只想要可执行文件的HMODULE,为什么不枚举进程中的所有HMODULE \\(EnumProcessModules)。其中之一将链接您的.lib。
我看到的限制是您不知道您的.lib来自哪个DLL或EXE。您可能想将HMODULE(基地址)与从.lib中获得的_ReturnAddress进行比较。您的.lib将属于小于_ReturnAddress
的最高HMODLUE