How can I get HINSTANCE from a DLL?
I have created a DLL in VC++ as Win32 project
DLLMAI开发者_StackOverflow社区N function is
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
Now I need HINSTANCE of the DLL , that need to be passed to Win32 functions.
Are HMODULE and HINSTANCE same?
How can I get HINSTANCE?
An excerpt from the book Windows Via C/C++ [1]
Note As it turns out, HMODULEs and HINSTANCEs are exactly the same thing. If the documentation for a function indicates that an HMODULE is required, you can pass an HINSTANCE and vice versa. There are two data types because in 16-bit Windows HMODULEs and HINSTANCEs identified different things
[1] Richter, Jeffery and Nasarre, Christophe, Windows Via C/C++, 5th ed, Redmond: Microsoft Press 2008, pp. 74
Microsoft linker specific
#include "windows.h"
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#pragma warning(disable: 4047)
HINSTANCE hInstance = (HINSTANCE)&__ImageBase;
#pragma warning(default: 4047)
I think that these are the same. If you want HINSTANCE of the running process (exe), you should use
GetModuleHandle(NULL);
Calling GetModuleHandle(NULL) from a dll will return the Hinstanc of the EXE that started the DLL; to get the Hinstance for the curently running dll try this tip:
http://www.dotnet247.com/247reference/msgs/13/65259.aspx
DllMain function as it's described in MSDN:
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
Each DLL has at least a header file, say MyDll.h and a corresponding implementation file MyDll.cpp. Open the header file and add
extern HMODULE hDllModule;//or whatever name you like
Now open the MyDll.cpp file. There is a function DLLMAIN. Add before it HMODULE hDllModule;
and insert hDllModuleDll = hModule;
before return true;
. Your code will look like this:
HMODULE hDllModuleDll;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
hDllModuleDll = hModule;
return TRUE;
}
In functions like ::GetModuleFileNameW(hModule, PathFile, MAX_PATH);
that require a HMODULE
of the DLL you can pass the global variable hDllModule
.
To complement the other answers, for the sake of completness.
The actual signature of DllMain
has an HINSTANCE
parameter, instead of a HMODULE
parameter. The Visual Studio DLL template generates the signature with HMODULE
since at least Visual Studio 2008 however, but I believe this to be a minor bug more than anything. VC6 generated the code with HANDLE
(even though both HINSTANCE
and HMODULE
exist). The reason that doesn't cause problems is because HINSTANCE
and HMODULE
are now exactly the same thing. Unfortunately I was unable to find an ancient enough version of the MSDN documetnation that could have confirmed this.
So the answer is: You get your HINSTANCE
as an argument to your DllMain
.
Personally I sort of like the distinction between HMODULE and HINSTANCE because it appeals to me as being good code hygiene. It's a bit like using const
. But then, a new question arises: Given your HINSTANCE
, how do you get your HMODULE
in the "hygienic" way?
The windowsx.h
header defines GetInstanceModule
, which is now a macro that just casts the HINSTANCE
to HMODULE
. It only exists for code compatibility, along with a bunch of very similar macros.
精彩评论