關於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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM