我不想使用DllMain中保存全局句柄的方法。
说明:
(1) MFC扩展DLL中
int DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 第一个参数即为DLL句柄
(2)WIN32DLL中
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 第一个参数即为DLL句柄
(3) WIN32勾选MFC选项的DLL中,要获取DLL句柄,就比较麻烦。
例如:DownLoaderDLLTest.exe中动态加载DownLoaderDLL.dll后,就算在DLL中通过GetModuleHandle()获取的也是exe的句柄,而不是dll的,
除非指定dll名称,HMODULE hDll = ::GetModuleHandle("DownLoaderWin32MfcDLL.dll"); 这样才可以获取dll模块句柄,
但是,通常条件下我们的模块名称不能写死,
<strong>方法1</strong>: 注意:TRUE会导致DLL引用计数加1,FALSE不会改变引用计数,通常用FALSE HMODULE GetCurrentModule(BOOL bRef/* = FALSE*/) { HMODULE hModule = NULL; if (GetModuleHandleEx(bRef ? GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS : (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT), (LPCSTR)GetCurrentModule, &hModule)) { return hModule; } return NULL; }
方法2: 参考:http://blog.csdn.net/yaosan/article/details/3459756 HMODULE GetSelfModuleHandle() { MEMORY_BASIC_INFORMATION mbi; return ((::VirtualQuery(GetSelfModuleHandle, &mbi, sizeof(mbi)) != 0) ? (HMODULE) mbi.AllocationBase : NULL); }
附加说明:
GetModuleHandle()与GetModuleHandleEx()
这两个函数都是用于获取"已经映射到调用进程中"的模块的句柄。
1.GetModuleHandle(lpModuleName)
lpModuleName是模块的名称,可以是**.dll或者**.exe,如果没有扩展名,则默认为dll.
如果模块名称通过路径来指定,则路径中必须使用"\",而不是"/".
执行时,该函数通过名称(大小写不敏感)来查看调用进程已映射的模块,返回符合的模块句柄。
如果GetModuleHandle(NULL),则返回调用进程本身的句柄。
成功,则返回句柄,失败,返回NULL。错误信息:GetLastError()
ps:
GetModuleHandle函数不会增加所指定模块的引用数,也就是说,不管调用该函数几次,只要调用一次FreeLibrary函数,该模块就从进程中卸载了。
在多线程中,模块句柄在不同线程中不总是有效的。如:当在一个线程中调用了该函数获取了某一模块的句柄,但在使用该句柄之前,另一个线程把该句柄
Free了,并重新获取了其他模块的句柄。这个时候第一个线程再去使用这个句柄变量,就不再是之前它打算操作的那个模块了,而是第二个线程修改后的模块
句柄了。
2.GetModuleHandleEx(dwFlags, lpModuleName, phModule)
dwFlags:
如果是0,则当调用该函数时,模块的引用计数自动增加,调用者在使用完模块句柄后,必须调用一次FreeLibrary
如果是GET_MODULE_HANDLE_EX_FLAG_PIN,则模块一直映射在调用该函数的进程中,直到该进程结束,不管调用多少次FreeLibrary
如果是GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,则同GetModuleHandle相同,不增加引用计数
如果是GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,则lpModuleName是模块中的一个地址
phModule存储要找的句柄。其他都和GetModuleHandle函数相同