DLL中如何获取自身的句柄

如题:
一个EXE加载了一个DLL。我想在DLL中动态的获取DLL本身的实例句柄.有没有什么方法?

我不想使用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模块句柄,

          但是,通常条件下我们的模块名称不能写死,

方法1:
注意: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()说明

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函数相同


你可能感兴趣的:(DLL,VC/MFC)