DLL入口点函数DllMain
生活随笔
收集整理的這篇文章主要介紹了
DLL入口点函数DllMain
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
每個DLL都可以有一個入口點函數DllMain,系統會在不同的時刻調用此函數。以下是DllMain的一般形式:
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL moduleDWORD fdwReason, // reason for calling functionLPVOID lpReserved ) // reserved {// Perform actions based on the reason for calling.switch( fdwReason ) { case DLL_PROCESS_ATTACH:// Initialize once for each new process.// Return FALSE to fail DLL load.break;case DLL_THREAD_ATTACH:// Do thread-specific initialization.break;case DLL_THREAD_DETACH:// Do thread-specific cleanup.break;case DLL_PROCESS_DETACH:// Perform any necessary cleanup.break;}return TRUE; // Successful DLL_PROCESS_ATTACH. } 以上代碼摘自MSDN,幾乎所有的DllMain都以這種形式呈現。 先來看一下這個函數傳遞進來的參數: 1、 HINSTANCE hinstDLL 這個參數是該DLL實例的句柄,也就是此DLL映射到進程地址空間后,在該進程地址空間中的位置。 2、 DWORD fdwReason 此參數標示了調用DllMain函數的原因。有四種值,就是函數中case后的取值。各個取值的含義,稍后論述。 3、 LPVOID lpReserved 保留。 現在我們來討論一下fdwReason的四種取值,這些取值,也直接反映了操作系統會在何種情況下調用DllMain。 1、DLL_PROCESS_ATTACH 當系統第一次將一個DLL映射到進程地址空間中時,會調用DllMain,并為fdwReason傳入DLL_PROCESS_ATTACH。 注意,只有在第一次映射的時候,才會這樣。如之后,另一線程再次顯式加載此DLL,則操作系統只是增加該DLL的使用計數,而不會再次使用DLL_PROCESS_ATTACH來調用DllMain。 對DLL_PROCESS_ATTACH的處理,代表了DLL的初始化。 DllMain的返回值,也是針對DLL_PROCESS_ATTACH消息的。對于其余的三種取值,不起作用。 對于隱式加載,如DllMain返回FALSE,則程序會啟動失敗。對于顯式加載,則會使LoadLibrary返回NULL。 2、DLL_PROCESS_DETACH 當系統將一個DLL從進程地址空間中撤銷映射時,則會向DllMain傳入DLL_PROCESS_DETACH。我們應當在此處放置一些清理代碼。 當使用FreeLibrary時,如該線程的使用計數為0時,操作系統才會使用DLL_PROCESS_DETACH來調用DllMain。如使用計數大于0,則只是單純的減少該DLL的計數。 3、DLL_THREAD_ATTACH 當進程創建一個線程,則系統會檢查當前已映射到該進程空間中的所有DLL映像,并用DLL_THREAD_ATTACH來調用每個DLL的DllMain。 只有當所有DLL都完成了對DLL_THREAD_ATTACH的處理后,新線程才會執行它的線程函數。 另外,主線程不可能用DLL_THREAD_ATTACH來調用DllMain,因為主線程必然是在進程初始化的時候,用DLL_PROCESS_ATTACH調用DllMain的。 4、DLL_THREAD_DETACH 線程若要終止,會調用ExitThread,但是此函數不會立即終止線程,而是會利用DLL_THREAD_DETACH來調用當前進程地址空間中的所有DLL鏡像的DllMain. 當每個DLL的DllMain都處理完后,系統才會真正的結束線程。 最后看一下DllMain的序列化調用 舉個例子: 進程中有兩個線程,A與B。進程的地址空間中,映射了一個名為SomeDll.dll的DLL。兩個線程都準備通過CreateThread來創建另兩個線程,C和D。 當線程A調用CreateThread來創建線程C的時候,系統會用DLL_THREAD_ATTACH來調用SomeDll.dll的DllMain,當線程C執行其中代碼的時候,線程B調用CreateThread來創建線程D。 這時,系統同樣會用DLL_THREAD_ATTACH來調用SomeDll.dll的DllMain,這次是讓線程D來執行其中的代碼。 但是此時,系統會對DllMain執行序列化,它會將線程D掛起,直至線程C執行完DllMain中的代碼返回為止。 當C線程執行完DllMain中的代碼并返回時,可以繼續執行C的線程函數。此時,系統會喚醒線程D,讓D執行DllMain中的代碼。當返回后,線程D開始執行線程函數。總結
以上是生活随笔為你收集整理的DLL入口点函数DllMain的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]Create Custom Exc
- 下一篇: Cstring转化为String