如何获得当前执行的代码的HMODULE ?

时间:2022-05-19 07:22:52

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.

我有一个静态库,可以链接到.exe或.dll中。在运行时,我想要我的库函数的ony,以获得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?

有没有一种更好的方法来做到这一点看起来不那么陈腐?

(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资源,我知道我的用户将在与我的静态库同时链接这些资源。)

4 个解决方案

#1


44  

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

  return hModule;
}

#2


25  

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

__ImageBase是一个链接器生成的符号,它是模块的DOS头(仅MSVC)。您可以将其地址转换为HINSTANCE或HMODULE。所以它比通过API更方便。

So you just need to do this:

你只需要这样做:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)

From http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx

从http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx

#3


3  

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.

我将使用标记GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS查看GetModuleHandleEx()。看起来您可以更改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.

我没试过,但我觉得你想怎么做就怎么做。

#4


-4  

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是模块的基本地址。我来看看它是怎么工作的。但是,如果您想要的只是可执行文件的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

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

#1


44  

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

  return hModule;
}

#2


25  

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

__ImageBase是一个链接器生成的符号,它是模块的DOS头(仅MSVC)。您可以将其地址转换为HINSTANCE或HMODULE。所以它比通过API更方便。

So you just need to do this:

你只需要这样做:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)

From http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx

从http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx

#3


3  

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.

我将使用标记GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS查看GetModuleHandleEx()。看起来您可以更改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.

我没试过,但我觉得你想怎么做就怎么做。

#4


-4  

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是模块的基本地址。我来看看它是怎么工作的。但是,如果您想要的只是可执行文件的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

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