DLL入口點函式DllMain

2021-07-24 17:36:43 字數 2237 閱讀 5583

每個dll都可以有乙個入口點函式dllmain,系統會在不同的時刻呼叫此函式。以下是dllmain的一般形式:

bool winapi dllmain(

hinstance hinstdll, // handle to dll module

dword fdwreason, // reason for calling function

lpvoid lpreserved ) // reserved

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

bool apientry dllmain hmodule hmodule,dword ul reason for call,lpvoid lpreserved return true 通過第二個引數ul reason for call來區分當前dll狀態 dll process attach 當乙...

C 程式入口點函式

cui控制台程式 不是dos,沒有介面的 main 其中處理unicode字元和字串的cui應用程式是 tmain main 處理 字元和字串的cui應用程式是 tamin wmain gui使用者介面程式 winmain 其中處理unicode字元和字串的gui應用程式是 twinmain wwi...

Dll入口函式引數詳解

dll程式入口點函式 dllmain,注意 大小寫是區別的 僅匯出資源的dll可以沒有dllmain函式 函式原型 bool apientry dllmain hmodule hmodule,dword ul reason for call,lpvoid lpreserved 引數意義 hmodul...