Reputation: 18635
I have a static library that may get linked into either a .exe
or a .dll
. At runtime I want one 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.)
Upvotes: 40
Views: 52926
Reputation: 54624
__ImageBase
is a linker generated symbol that is the DOS header of the module (MSVC only). From that you can cast its address to an HINSTANCE
or HMODULE
. So it's more convenient than going through an API.
So you just need to do this:
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
Upvotes: 33
Reputation: 1275
#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
}
More here https://www.apriorit.com/dev-blog/74-hmodule-hinstance-handle-from-static-library-in-c
Upvotes: 0
Reputation: 8926
I'd look at GetModuleHandleEx()
using the flag GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
. It looks like you can change your GetCurrentModule()
to call this routine instead of VirtualQuery()
, and pass the address of GetCurrentModule()
as the lpModuleName
argument.
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;
}
I didn't try it, but I think that'll do what you want.
Upvotes: 5
Reputation: 21888
HMODULE GetCurrentModule()
{ // NB: XP+ solution!
HMODULE hModule = NULL;
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModule,
&hModule);
return hModule;
}
Upvotes: 60
Reputation: 179981
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
Upvotes: -4