How do I get the HMODULE for the currently executi

2020-01-24 04:20发布

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.)

标签: c++ c winapi
4条回答
闹够了就滚
2楼-- · 2020-01-24 04:52

__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)

From https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483

查看更多
家丑人穷心不美
3楼-- · 2020-01-24 04:56

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

查看更多
不美不萌又怎样
4楼-- · 2020-01-24 05:01

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.

查看更多
一纸荒年 Trace。
5楼-- · 2020-01-24 05:02
HMODULE GetCurrentModule()
{ // NB: XP+ solution!
  HMODULE hModule = NULL;
  GetModuleHandleEx(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
    (LPCTSTR)GetCurrentModule,
    &hModule);

  return hModule;
}
查看更多
登录 后发表回答