DllMain说明及如何获取DLL路径

1、DllMain可有可无

一般在C或C++中,DLL的模块入口点有个默认函数,是_DllMainCRTStartup(),它的原形与 DllMain()一样,链接器在链接的时候就是以它作为模块的入口函数,那样它就可以进行一些模块全局变量等的初始化操作,当然用户也可对模块入口地址 进行自行设定,不过不建议这么做!

当链接器在链接时,它会自动查找当前DLL模块工程中的各个.obj文件,如果找到有DllMain()函数,这时就会 在_DllMainCRTStartup()函数中调用用户的入口点函数,也就是DllMain()函数;如果找不到,就会调用到CRT的默认DllMain(),这个DllMain()函数中只有很少的一些代码,那就是在传递DLL_PROCESS_ATTACH通知中调用 DisableThreadLibraryCalls()函数,以告诉系统以后有线程的创建或撤消时不必调用此DLL的入口点通知。  

所以说在DLL模块中没有DllMain()用户自定义的入口点模块是可以的。


2、获取DLL的路径

分两种情况:有DllMain和无DllMain。两种情况下获取的方法有所不同。

(1)有DllMain入口函数

如果dll中有DllMain入口函数,则比较简单,DllMain的第一个参数就是DLL句柄,直接获取即可:

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	g_hDLLInstance = hModule;
	// 直接使用hModule参数来获取
	TCHAR achDllPath[MAX_PATH] = { 0 };
	GetModuleFileName( hModule, achDllPath, sizeof(achDllPath)/sizeof(TCHAR) );
(2)没有DllMain入口函数

DLL中允许没有DllMain函数,上面已经说明。那此时如何获取当前Dll的路径呢?使用下面的代码来获取当前DLL句柄:

/****************************************************************************
使用下面的HMODULE GetCurrentModule()可以获取dll自己的句柄。
接着使用
TCHAR lib_name[MAX_PATH]; 
::GetModuleFileName( GetCurrentModule(), lib_name, MAX_PATH );
就可以获取dll的路径了
 
Most DLL developers have faced the challenge of detecting a HMODULE/HINSTANCE handle 
within the module you're running in. It may be a difficult task if you wrote the DLL 
without a DLLMain() function or you are unaware of its name. For example:
Your DLL was built without ATL/MFC, so the DLLMain() function exists, 
but it's hidden from you code and you cannot access the hinstDLL parameter. 
You do not know the DLL's real file name because it could be renamed by everyone, 
so GetModuleHandle() is not for you.
This small code can help you solve this problem:
****************************************************************************/
#if _MSC_VER >= 1300    // for VC 7.0
// from ATL 7.0 sources
#ifndef _delayimp_h
extern "C" IMAGE_DOS_HEADER __ImageBase;
#endif
#endif
 
static
HMODULE GetCurrentModule()
{
#if _MSC_VER < 1300    // earlier than .NET compiler (VC 6.0)
     
    // Here's a trick that will get you the handle of the module
    // you're running in without any a-priori knowledge:
    MEMORY_BASIC_INFORMATION mbi;
    static int dummy;
    VirtualQuery( &dummy, &mbi, sizeof(mbi) );
     
    return reinterpret_cast(mbi.AllocationBase);
#else    // VC 7.0
    // from ATL 7.0 sources
    return reinterpret_cast(&__ImageBase);
#endif
}
获取到DLL句柄,调用GetModuleFileName API函数即可获取当前DLL的路径了。

你可能感兴趣的:(资料集)