【问题标题】:How can I get HINSTANCE from a DLL?如何从 DLL 中获取 HINSTANCE?
【发布时间】:2010-01-24 10:15:43
【问题描述】:

我在 VC++ 中创建了一个 DLL 作为 Win32 项目

DLLMAIN 函数是

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    return TRUE;
}

现在我需要 DLL 的 HINSTANCE,它需要传递给 Win32 函数。

HMODULE 和 HINSTANCE 一样吗?

如何获得 HINSTANCE?

【问题讨论】:

    标签: winapi visual-c++


    【解决方案1】:

    摘自 Windows Via C/C++ [1] 一书

    注意事实证明,HMODULEs 和 HINSTANCEs 是完全一样的。如果函数的文档表明需要 HMODULE,则可以传递 HINSTANCE,反之亦然。有两种数据类型,因为在 16 位 Windows 中 HMODULEs 和 HINSTANCEs 识别不同的东西

    [1] Richter, Jeffery and Nasarre, Christophe, Windows Via C/C++,第 5 版,Redmond:Microsoft Press 2008,第 74 页

    【讨论】:

    • Win32、HINSTANCE 和 HMODULE 都是模块的基地址。
    【解决方案2】:

    Microsoft 链接器特定

    #include "windows.h"
    EXTERN_C IMAGE_DOS_HEADER __ImageBase;
    #pragma warning(disable: 4047)
    HINSTANCE hInstance = (HINSTANCE)&__ImageBase;
    #pragma warning(default: 4047)
    

    【讨论】:

    • 如果DLL被重定位怎么办?
    【解决方案3】:

    我认为这些是相同的。如果你想要运行进程(exe)的HINSTANCE,你应该使用

    GetModuleHandle(NULL);
    

    【讨论】:

    • 这不会返回 DLLHMODULE,这是 OP 所要求的。
    【解决方案4】:

    从 dll 调用 GetModuleHandle(NULL) 将返回启动 DLL 的 EXE 的 Hinstanc;要获取当前运行的 dll 的 Hinstance,请尝试以下提示:

    http://www.dotnet247.com/247reference/msgs/13/65259.aspx

    【讨论】:

    【解决方案5】:

    MSDN 中描述的 DllMain 函数:

    BOOL WINAPI DllMain(
      __in  HINSTANCE hinstDLL,
      __in  DWORD fdwReason,
      __in  LPVOID lpvReserved
    );
    

    http://msdn.microsoft.com/en-us/library/ms682583%28v=vs.85%29.aspx

    【讨论】:

      【解决方案6】:

      每个 DLL 至少有一个头文件,比如 MyDll.h 和一个相应的实现文件 MyDll.cpp。打开头文件并添加

      extern HMODULE hDllModule;//or whatever name you like 
      

      现在打开 MyDll.cpp 文件。有一个函数DLLMAIN。在它之前添加HMODULE hDllModule; 并在return true; 之前插入hDllModuleDll = hModule;。您的代码将如下所示:

      HMODULE hDllModuleDll;
      BOOL APIENTRY DllMain( HMODULE hModule,
                         DWORD  ul_reason_for_call,
                         LPVOID lpReserved
                       )
      {
        hDllModuleDll = hModule;
        return TRUE;
      }
      

      在像::GetModuleFileNameW(hModule, PathFile, MAX_PATH); 这样需要DLL 的HMODULE 的函数中,您可以传递全局变量hDllModule

      【讨论】:

        【解决方案7】:

        为了完整起见,补充其他答案。

        DllMain 的实际签名有一个HINSTANCE 参数,而不是HMODULE 参数。 Visual Studio DLL 模板使用HMODULE 生成签名,至少从 Visual Studio 2008 开始,但我认为这只是一个小错误。 VC6 使用HANDLE 生成代码(即使HINSTANCEHMODULE 都存在)。不会引起问题的原因是因为HINSTANCE and HMODULE are now exactly the same thing。不幸的是,我找不到可以证实这一点的足够古老的 MSDN 文档版本。

        所以答案是:您将HINSTANCE 作为DllMain 的参数。

        就我个人而言,我有点喜欢 HMODULE 和 HINSTANCE 之间的区别,因为它对我来说是良好的代码卫生。这有点像使用const。但是,一个新的问题出现了:鉴于您的HINSTANCE,您如何以“卫生”的方式获得您的HMODULE

        windowsx.h 标头定义了GetInstanceModule,它现在是一个宏,它只是将HINSTANCE 转换为HMODULE。它只是为了代码兼容性而存在,还有一堆非常相似的宏。

        【讨论】:

          猜你喜欢
          • 2011-06-13
          • 2019-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-15
          • 1970-01-01
          • 2014-10-10
          相关资源
          最近更新 更多