C++ 如何获取当前正在执行的代码的 HMODULE?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/557081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:57:09  来源:igfitidea点击:

How do I get the HMODULE for the currently executing code?

c++cwinapi

提问by pauldoo

I have a static library that may get linked into either a .exeor a .dll. At runtime I want ony of my library functions to get the HMODULEfor whatever thing the static library code has been linked into.

我有一个静态库,它可能会链接到 a.exe.dll. 在运行时,我希望我的任何库函数能够获取HMODULE静态库代码已链接到的任何内容。

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?

有没有更好的方法来做到这一点,看起来不那么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.)

(注意:这样做的目的是加载一些我知道我的用户将与我的静态库同时链接的 Win32 资源。)

回答by Serge Wautier

HMODULE GetCurrentModule()
{ // NB: XP+ solution!
  HMODULE hModule = NULL;
  GetModuleHandleEx(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
    (LPCTSTR)GetCurrentModule,
    &hModule);

  return hModule;
}

回答by MSN

__ImageBaseis a linker generated symbol that is the DOS header of the module (MSVC only). From that you can cast its address to an HINSTANCEor HMODULE. So it's more convenient than going through an API.

__ImageBase是链接器生成的符号,它是模块的 DOS 标头(仅限 MSVC)。从中您可以将其地址转换为HINSTANCEor HMODULE。所以它比通过 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

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

回答by Rob K

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

我会考虑GetModuleHandleEx()使用 flag GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS。看起来您可以更改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;
}

I didn't try it, but I think that'll do what you want.

我没有尝试,但我认为这会做你想做的。

回答by MSalters

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.

HMODULE 是 HINSTANCE 是模块的基地址。所以,我会看看它是如何工作的。但是,如果您想要的只是可执行文件的 HMODULE,为什么不枚举进程中的所有 HMODULE(EnumProcessModules)。其中之一将链接您的 .lib。

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

我看到的限制是您不知道您的 .lib 来自哪个 DLL 或 EXE。您可能希望将 HMODULE(基地址)与从 .lib 获得的 _ReturnAddress 进行比较。您的 .lib 将属于小于您的 _ReturnAddress 的最高 HMODLUE