I have a static library that may get linked into either a .exe
or a .dll
. At runtime I want ony of my library functions to get the HMODULE
for whatever thing the static library code has been linked into.
I currently use the following trick (inspired from this forum):
const HMODULE GetCurrentModule()
{
MEMORY_BASIC_INFORMATION mbi = {0};
::VirtualQuery( GetCurrentModule, &mbi, sizeof(mbi) );
return reinterpret_cast<HMODULE>(mbi.AllocationBase);
}
Is there a better way to do this that doesn't look so hacky?
(Note: The purpose of this is to load some Win32 resources that I know my users will have linked in at the same time as my static library.)
__ImageBase
is a linker generated symbol that is the DOS header of the module (MSVC only). From that you can cast its address to anHINSTANCE
orHMODULE
. So it's more convenient than going through an API.So you just need to do this:
From https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483
The HMODULE is the HINSTANCE is the base address of the module. So, I'd see how it worked. But if all you want is the HMODULE of the executable, why not enumerate all HMODULE's in the process (EnumProcessModules). One of them will have your .lib linked in.
The limitation I see is that you have no idea which DLL or EXE your .lib comes from. You might want to compare the HMODULEs (base addresses) against the _ReturnAddress you get from your .lib. Your .lib will belong to the highest HMODLUE smaller than your _ReturnAddress
I'd look at
GetModuleHandleEx()
using the flagGET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
. It looks like you can change yourGetCurrentModule()
to call this routine instead ofVirtualQuery()
, and pass the address ofGetCurrentModule()
as thelpModuleName
argument.ETA:
I didn't try it, but I think that'll do what you want.