Dllmain的作用
DllMain函數是DLL模塊的默認入口點。當Windows加載DLL模塊時調用這一函數。系統首先調用全局對象的構造函數,然后調用全局函數 DLLMain。DLLMain函數不僅在將DLL鏈接加載到進程時被調用,在DLL模塊與進程分離時(以及其它時候)也被調用。
DLL程序入口點函數:DllMain,注意:大小寫是區別的(僅導出資源的DLL可以沒有DllMain函數)。
函數原型:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }
參數意義:
①hModule參數:指向DLL本身的實例句柄;
②ul_reason_for_call參數:指明了DLL被調用的原因,可以有以下4個取值:
1. DLL_PROCESS_ATTACH:
當DLL被進程 <<第一次>> 調用時,導致DllMain函數被調用,
同時ul_reason_for_call的值為DLL_PROCESS_ATTACH,
如果同一個進程后來再次調用此DLL時,操作系統只會增加DLL的使用次數,
不會再用DLL_PROCESS_ATTACH調用DLL的DllMain函數。
2.DLL_PROCESS_DETACH:
當DLL被從進程的地址空間解除映射時,系統調用了它的DllMain,傳遞的ul_reason_for_call值是DLL_PROCESS_DETACH。
★如果進程的終結是因為調用了TerminateProcess,系統就不會用DLL_PROCESS_DETACH來調用DLL的DllMain函數。這就意味着DLL在進程結束前沒有機會執行任何清理工作。
3.DLL_THREAD_ATTACH:
當進程創建一線程時,系統查看當前映射到進程地址空間中的所有DLL文件映像,
並用值DLL_THREAD_ATTACH調用DLL的DllMain函數。
新創建的線程負責執行這次的DLL的DllMain函數,
只有當所有的DLL都處理完這一通知后,系統才允許線程開始執行它的線程函數。
4.DLL_THREAD_DETACH:
如果線程調用了ExitThread來結束線程(線程函數返回時,系統也會自動調用ExitThread),
系統查看當前映射到進程空間中的所有DLL文件映像,
並用DLL_THREAD_DETACH來調用DllMain函數,
通知所有的DLL去執行線程級的清理工作。
★注意:如果線程的結束是因為系統中的一個線程調用了TerminateThread,
系統就不會用值DLL_THREAD_DETACH來調用所有DLL的DllMain函數。
③lpReserved參數:隱士加載和顯示加載時,此參數值不一樣,顯示加載時為零,如果用戶希望限定動態鏈接庫的加載形式可以通過判斷這個參數的值實現。
動態庫的隱示加載 需要頭文件 lib文件 dll文件 程序運行時dll也要加載到內容 但多個程序使用dll時 內存中只用一份dll
動態庫的顯示加載 只需要dll文件即可 程序運行時不加載dll 只有在loadlibrary 使用庫函數時才加載dll
動態庫的延遲加載其實是動態庫的隱示加載和顯示加載的合並 需要頭文件 lib文件 dll文件 只是程序運行時不加載dll,在程序使用時才加載dll,此時的原理與顯示加載的原理一樣。編譯器選項中配置 link>delay load dll一項需要填入加載的動態庫文件
程序運行時需要知道動態庫的路徑 可以通過setdlldirctrory()可以指定動態庫的路徑