MFC 將 DLL 分為三大類,按對 MFC 庫的依賴方式與導出能力劃分:
extern "C"),可被任何語言調用。使用 MFC 類庫,特徵是包含一個繼承自 CWinApp 的類。細分兩種:
| 類型 | MFC 鏈接方式 | 特點 | 導出函數要求 |
|---|---|---|---|
| 靜態鏈接 MFC | 將 MFC 代碼編譯進 DLL | 體積大(~200KB+),無外部 MFC DLL 依賴;僅 VC 專業版/企業版支持 | extern "C" EXPORT ReturnType FuncName();(無需 AFX_MANAGE_STATE) |
| 動態鏈接 MFC | 運行時載入 MFCx0.dll | 體積小,需目標機安裝對應 MFC 版本 | 每個導出函數開頭必須加 AFX_MANAGE_STATE(AfxGetStaticModuleState()) 切換模塊狀態 |
Regular DLL 可被所有支持 DLL 的語言調用,DllMain 由 MFC 提供,無需手寫。
CWinApp 派生對象,必須手寫 DllMain。DllMain 中調用 AfxInitExtensionModule,檢查返回值。CRuntimeClass 或資源,需導出初始化函數,在其中構造 CDynLinkLibrary 對象。InitInstance 中調用該初始化函數。DllMain(默認入口)
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: // 進程載入 DLL
// 初始化:分配 TLS、載入資源、創建全局對象
break;
case DLL_THREAD_ATTACH: // 線程載入 DLL
// 線程級初始化(較少用)
break;
case DLL_THREAD_DETACH: // 線程卸載 DLL
// 線程級清理
break;
case DLL_PROCESS_DETACH: // 進程卸載 DLL
// 釋放資源、銷毀全局對象
break;
}
return TRUE;
}
參數說明:
hModule:DLL 模塊句柄(實際為 _DGROUP 區段選擇子)。ul_reason_for_call:調用原因標志。lpReserved:保留參數。注意:TerminateProcess/TerminateThread 強制結束時不會調用 DllMain(DETACH),資源可能泄漏。
_DllMainCRTStartup(CRT 入口)若使用 C 運行庫(CRT)DLL 版本(多線程),必須指定入口為 _DllMainCRTStartup,實際初始化函數仍為 DllMain。其職責:
DllMain 與 RawDllMain(MFC 擴展 DLL 靜態鏈接時需要)。