前言
VC++ 6.0 支援三種 DLL 專案類型,各自適用場景、MFC 依賴關係、發布體積與效能特性截然不同。本文依據 MSDN 官方指引,系統對比 Non-MFC DLL、Regular DLL (靜態/動態連結 MFC)、Extension DLL 的特性,提供選型決策樹與發布清單。
三種 DLL 類型定義
| 類型 | 建立精靈 | MFC 依賴 | 典型用途 |
| Non-MFC DLL | Win32 Application Wizard → DLL | 無 | 純 C 掛介面、數學庫、演算法、跨語言 (C#/VB/Python) 呼叫 |
| Regular DLL (MFC 正規 DLL) | MFC DLL Wizard | 靜態或動態連結 MFC | 封裝 MFC 類別/對話框/控件,供 MFC 或非 MFC EXE 使用 |
| Extension DLL (MFC 擴展 DLL) | MFC DLL Wizard | 動態連結 MFC (強制) | 導出繼承自 MFC 的類別、在 EXE 與 DLL 間傳遞 MFC 物件指標 |
Regular DLL 兩種連結模式深度對比
| 維度 | 動態連結 MFC | 靜態連結 MFC |
| DLL 體積 | 小 (僅含業務碼) | 大 (含 MFC 靜態庫副本) |
| 記憶體佔用 | 共享 MFC DLL (MFC42.DLL 等) | 每個 DLL 載入私有 MFC 副本 |
| 建置速度 | 快 (無需連結 MFC) | 慢 (需連結 MFC 靜態庫) |
| 調試資訊壓縮 | 少 (共享 DLL 已含調試資訊) | 多 (需壓縮私有副本調試資訊) |
| 發布依賴 | 需附帶 MFC42.DLL, MSVCRT.DLL | 獨立,無外部 MFC 依賴 |
| 版本衝突風險 | 可能 (DLL Hell) | 無 (私有副本隔離) |
選型決策樹 (MSDN 官方指引)
開始
│
├─ DLL 是否使用 MFC 類別/功能?
│ ├─ 否 → 【Non-MFC DLL】 (最輕量、跨語言最佳)
│ └─ 是
│ │
│ ├─ 是否由非 MFC EXE (如 VB, C#, 純 C) 呼叫?
│ │ ├─ 是 → 【Regular DLL 動態連結 MFC】 (體積小、共享 MFC)
│ │ └─ 否 (僅 MFC EXE 呼叫)
│ │ │
│ │ ├─ 是否導出「繼承自 MFC 類別」或「傳遞 MFC 物件指標」?
│ │ │ ├─ 是 → 【Extension DLL】 (強制動態連結 MFC)
│ │ │ └─ 否 → 【Regular DLL】 (動態/靜態視體積/部署取捨)
│ │ │
│ │ └─ 部署考量:
│ │ ├─ 體積/記憶體敏感、可接受附帶 MFC DLL → 動態連結
│ │ └─ 追求零依賴、隔離版本衝突 → 靜態連結
│ │
└─ 結束
Extension DLL 獨特能力
- 導出
class __declspec(dllexport) CMyDoc : public CDocument 等繼承 MFC 類別
- EXE 與 DLL 共享 同一個 MFC 狀態模組 (模組狀態、資源鏈、當前
AfxGetApp())
- 支援
CDynLinkLibrary 機制自動匯出資源 (對話框模板、圖示、字串表)
- EXE 可直接
dynamic_cast、傳遞 CWnd*/CDocument* 等 MFC 物件指標給 DLL
發布清單
| DLL 類型 | 必須隨附檔案 | 安裝注意事項 |
| Non-MFC DLL | 僅 DLL 本身 (+ 相依 C Runtime 若動態連結) | 系統目錄或應用目錄均可 |
| Regular DLL (動態) | DLL + MFC42.DLL (或對應版本) + MSVCRT.DLL | MFC DLL 必須安裝至系統目錄 (System32/SysWOW64) 或 WinSxS |
| Regular DLL (靜態) | 僅 DLL 本身 | 無額外依賴,但體積較大 |
| Extension DLL | DLL + MFC42.DLL + MSVCRT.DLL | 同動態 Regular DLL,且 EXE 必須同樣動態連結 MFC |
常見誤區與避坑
- 誤以為 Extension DLL 可供非 MFC EXE 使用:錯誤。Extension DLL 依賴 MFC 模組狀態,呼叫端必須是 MFC EXE 或 Regular DLL。
- Regular DLL 靜態連結 MFC 卻在 DLL 內使用
AfxGetApp():會取得 DLL 自己的 CWinApp,非 EXE 的,導致資源載入錯誤。需用 AfxGetResourceHandle() 管理資源鏈。
- 混用 Debug/Release 版 MFC DLL:嚴禁。Debug 版 MFC (MFC42D.DLL) 與 Release 版 (MFC42.DLL) 不可混載。
總結
選型核心原則:能用 Non-MFC 就不用 MFC;能用 Regular 就不用 Extension;能動態連結就別靜態連結 (除非部署極度受限)。理解三種 DLL 的 MFC 狀態模型、資源鏈管理、物件指標傳遞邊界,是構建穩健、可維護、可部署的模組化 Windows 應用基石。