关于dllmain的百度百科的学习。

 

一个程序要调用dll里的函数,首先要将此dll文件映射到程序进程的地址空间(从磁盘文件映射到内存地址空间 ,PE文件装载器读取),要把dll文件映射到程序进程的地址空间有两种方法:静态链接和动态链接的LoadLibrary或者LoadLibraryEx

程序要调用DLL里的函数,使用Loadliabrary时,会调用DLLMain函数。

当一个dll被映射到进程的地址空间时,系统会调用该dll的dllmain 函数,传递dwReason参数为DLL_PROCESS_ATTATCH,这种调用只会发生在第一次调用,如果同一进程为后来已经映射进来的dll再次调用LoadLibrary或者LoadLibraryEx,操作系统只会增加dll的调用次数,他不会再用DLL_PROCESS_ATTATCH调用DLL的DLLMAIN。

 *****************************************************************

我们知道,在MFC应用程序中CWinApp取代了SDK程序中WinMain的地位,SDK程序WinMain所完成的工作由CWinApp的三个函数完成:

virtual BOOL InitApplication( );

virtual BOOL InitInstance( );

virtual BOOL Run( ); //传说中MFC程序的“活水源头”另外,MFC规则DLL与MFC 应用程序中一样,需要将所有 DLL中元素的初始化放到InitInstance 成员函数中。
可以试验一下dllmain的一次调用。增加InitInstance函数,如下:
BOOL CRegularDllApp::InitInstance() 
{
	// TODO: Add your specialized code here and/or call the base class
	CString dxs;
	dxs="dxsaslfll";
	AfxMessageBox(dxs);
	return CWinApp::InitInstance();
}在应用程序中调用时,如下函数,会首次调用InitInstance函数的AfxMessageBox dxsaslfll,再次点击按钮时候不在调用InitInstance.
 
void CRegularDllCallDlg::OnCalldllButton() 
{
	typedef void (*lpFun)(void);

	HINSTANCE hDll;   //DLL句柄	
	hDll = LoadLibrary("RegularDll.dll");
	if (NULL==hDll)
	{
		MessageBox("DLL加载失败");
	}	//lpFun addFun;  //函数指针
    lpFun pShowDlg = (lpFun)GetProcAddress(hDll,"ShowDlg");//指的是ShowDlg的返回为void 参数为void
	if (NULL==pShowDlg)
	{
		MessageBox("DLL中函数寻找失败");	
	}
    pShowDlg();/*	AfxMessageBox("dd");*/
}

 *****************************************************************

我用一个my.dll,自动联接av.dll,我用LoadLibrary("my.dll"),GetLastError返回
”指定的模块找不到“,再用LoadLibraryEx("my.dll",NULL,DONT_RESOLVE_DLL_REFERENCES)就ok.

(附:1. DONT_RESOLVE_DLL_REFERENCES,DONT_RESOLVE_DLL_REFERENCES标志用于告诉系统将DLL映射到调用进程的地址空间中。通常情况下,当DLL被映射到进程的地址空间中时,系统要调用 D L L中的一个特殊函数,即 DllMain。该函数用于对DLL进行初始化。 DONT_RESOLVE_DLL_REFERENCE S标志使系统不必调用Dll Main函数就能映射文件映像。
D L L能够输入另一个D L L中包含的函数。当系统将一个 D L L映射到进程的地址空间
中时,它也要查看该DLL是否需要其他的DLL,并且自动加载这些DLL。当DONT_RESOLVE _DLL_REFERENCES标志被设定时,系统并不自动将其他的DLL加载到进程的地址空间中。)

DLL难道是av.dll找不到,但av.dll是我在编译my.dll时加av.lib自动联上的,请问有什么直接的办法来检测自动联接的av.dll是否在LoadLibrary("my.dll")时是错误之根源??

 

LoadLibraryEx可设置 DONT_RESOLVE_DLL_REFERENCE使得系统不必调用dllmain函数就能映射dll文件。 DONT_RESOLVE_DLL_REFERENCES:不对DLL进行初始化,仅用于NT。