关于dllmain以及dll函数调用的理解。

关于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。

关于dllmain以及dll函数调用的理解。

上一篇:CentOS 修改主机名


下一篇:从敏捷开发到小团队SVN