开发者

How can I get HINSTANCE from a DLL?

开发者 https://www.devze.com 2022-12-17 04:05 出处:网络
I have created a DLL in VC++ as Win32 project DLLMAI开发者_StackOverflow社区N function is BOOL APIENTRY DllMain( HMODULE hModule,

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消