C++ GetModuleHandle(NULL) 与 hInstance
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21718027/
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
GetModuleHandle(NULL) vs hInstance
提问by Proxy
When programming using the Windows API, I've always made the HINSTANCE
from WinMain
a global variable immediately. If I want to make an OK button, I'd do it like so (given global HINSTANCE g_hInstance
):
在使用 Windows API 编程时,我总是立即HINSTANCE
从WinMain
全局变量中创建。如果我想制作一个 OK 按钮,我会这样做(给定 global HINSTANCE g_hInstance
):
return CreateWindow("BUTTON", "OK", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10, 100, 30, exampleParentWindow, EXAMPLECHILDID, g_hInstance, NULL);
but lately I've been seeing the instance handle determined without having to be passed as a parameter or clogging up the global namespace, using a call to GetModuleHandle(NULL)
*. So, the example above would look like this:
但是最近我看到实例句柄被确定而不必作为参数传递或阻塞全局命名空间,使用对GetModuleHandle(NULL)
*. 所以,上面的例子看起来像这样:
return CreateWindow("BUTTON", "OK", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10, 100, 30, exampleParentWindow, EXAMPLECHILDID, GetModuleHandle(NULL), NULL);
*If your compiler supports it, you can write GetModuleHandle(nullptr)
and the statement will have the same result.
*如果您的编译器支持它,您可以编写GetModuleHandle(nullptr)
并且语句将具有相同的结果。
What's the advantage (if any) of calling GetModuleHandle(NULL)
over explicitly specifying the instance handle?
调用GetModuleHandle(NULL)
显式指定实例句柄有什么好处(如果有的话)?
Fine Print: I know this has an answer, but it has not been phrased as its own question on StackOverflow.
Fine Print:我知道这有一个答案,但在 StackOverflow 上它没有被表述为它自己的问题。
回答by Remy Lebeau
In an EXE, it does not make any difference. hInstance
from WinMain()
and GetModuleHandle(NULL)
both refer to the same HINSTANCE
(the module of the .exe file). But it does make a difference if you are creating windows inside of a DLL instead, since you have to use the DLL's hInstance
but GetModuleHandle(NULL)
will still return the HINSTANCE
of the EXE that loaded the DLL.
在 EXE 中,它没有任何区别。hInstance
fromWinMain()
和GetModuleHandle(NULL)
两者都指的是同一个HINSTANCE
(.exe 文件的模块)。但是,如果您在 DLL 内创建窗口,确实会有所不同,因为您必须使用 DLL,hInstance
但GetModuleHandle(NULL)
仍会返回HINSTANCE
加载 DLL 的 EXE 的 。
回答by Tony Thomas
HMODULE WINAPI GetModuleHandle( _In_opt_ LPCTSTR lpModuleName );
Give the module handle of the module name passed.If you are passing NULL, the you get the module handle of the EXE which is currently running. If you specifically name the module name, you get the module handle of that dll which is mapped to the process address space. The use is that when you are trying to call a function exported by the dll, or trying to use a dialog template in side that dll.At that time if you use the HMODULE returned form GetMoudleHandle(NULL) your code wont work.
给出传递的模块名称的模块句柄。如果传递NULL,则获得当前正在运行的EXE 的模块句柄。如果您专门命名模块名称,您将获得映射到进程地址空间的那个 dll 的模块句柄。用途是当您尝试调用由 dll 导出的函数时,或尝试在该 dll 中使用对话框模板时。那时如果您使用 HMODULE 返回的 GetMoudleHandle(NULL) 形式,您的代码将无法工作。
回答by Hayden McParlane
One potential gain you get from using GetModuleHandle(NULL) over directly using the WinMain HINSTANCE comes more from architecture. If you want to provide a platform-independent system that runs on linux/windows/whatever you can have a layer that does platform-dependent translations. If that's the case you don't want platform dependent objects such as HINSTANCE showing up in the main application code. So, to circumvent that platform-dependence I put GetModuleHandle(NULL) in the constructor of the platform-dependent class which has the same effect that direct use of the WinMain HINSTANCE does but that abstracts that specific functionality out of the main codebase itself.
与直接使用 WinMain HINSTANCE 相比,使用 GetModuleHandle(NULL) 获得的一个潜在收益更多地来自体系结构。如果您想提供一个在 linux/windows/whatever 上运行的独立于平台的系统,您可以拥有一个执行依赖于平台的翻译的层。如果是这种情况,您不希望平台相关对象(如 HINSTANCE)出现在主应用程序代码中。因此,为了规避这种平台依赖性,我将 GetModuleHandle(NULL) 放在了平台相关类的构造函数中,该类的效果与直接使用 WinMain HINSTANCE 的效果相同,但将特定功能从主代码库本身中抽象出来。
回答by c00000fd
Just to add my two-cents to these answers. In case you need to get the module handle from within a DLL (and don't want to, or can't save it in a global variable from the DllMain
call) you can use this function to get it instead:
只是为了将我的两分钱添加到这些答案中。如果您需要从 DLL 中获取模块句柄(并且不想或无法通过DllMain
调用将其保存在全局变量中),您可以使用此函数来获取它:
HMODULE getThisModuleHandle()
{
//Returns module handle where this function is running in: EXE or DLL
HMODULE hModule = NULL;
::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCTSTR)getThisModuleHandle, &hModule);
return hModule;
}