| 類型 | 特點 | 適用場景 |
|---|---|---|
| MFC 擴展 DLL | 匯出 C++ 類別、MFC 型別參數;需動態連結 MFC DLL;客戶端也必須動態連結 MFC | MFC 應用程式之間共享複雜類別 |
| 一般 DLL (動態連結 MFC) | 介面限 C 風格函數/基本型別;內部可用 MFC;需目標機有 MFC DLL | 非 MFC 客戶端 (VB, C#, PB) 呼叫,內部用 MFC 方便 |
| 一般 DLL (靜態連結 MFC) | 同上,但 MFC 程式碼內建於 DLL,體積較大;目標機無需 MFC DLL | 部署環境不可控,追求獨立性 |
// 一般 DLL / 擴展 DLL 通用
class __declspec(dllexport) CMyClass { ... };
// 擴展 DLL 專用巨集 (自動處理 dllimport/dllexport)
class AFX_EXT_CLASS CMyClass { ... }
__declspec(dllexport) int g_nValue;
__declspec(dllexport) const COLORREF g_clrRed = RGB(255,0,0); // 常數必須加 extern
__declspec(dllexport) CRect g_rect(10,10,20,20);
每個載入進程擁有獨立副本,修改不影響其他進程。
// 一般 DLL (C 介面)
extern "C" __declspec(dllexport) int MyFunc(int x);
// 動態連結 MFC 一般 DLL 必須加 AFX_MANAGE_STATE
extern "C" __declspec(dllexport) int MyFunc(int x)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// MFC 代碼...
}
__declspec(dllexport) CMyClass* g_pObj = new CMyClass;
// 擴展 DLL: DllMain 清理
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_DETACH) delete g_pObj;
return TRUE;
}
// 一般 DLL: 覆寫 CWinApp::ExitInstance
int CMyDllApp::ExitInstance() { delete g_pObj; return CWinApp::ExitInstance(); }
.dll、.lib、匯出類別/函數 .h 到客戶專案目錄。Debug/MyDll.lib。__declspec(dllimport):__declspec(dllimport) int MyFunc(int);
__declspec(dllimport) CMyClass g_obj;
extern "C" __declspec(dllimport) int MyFunc(int);
建議建立共用標頭檔,用巨集切換:
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MYDLL_API CMyClass { ... };
MYDLL_API int MyFunc(int);
CString、檔案指標、new/delete 極易崩潰,**嚴禁跨 DLL 釋放對方配置的記憶體**。