本系列第二部分聚焦 非 MFC DLL (Non-MFC DLL):不依賴 MFC,導出標準 C 介面,可被任何語言調用。核心內容包括:導出函數聲明兩種方式(__declspec(dllexport) 與 .def 文件)、應用程式三種調用模式(隱式鏈接、顯式運行時鏈接、序號調用)。
File → New → Project → Win32 Dynamic-Link Library(非 MFC AppWizard)。dllTest,選擇 A simple DLL project。// lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int __declspec(dllexport) add(int x, int y);
#endif
// lib.cpp
#include "lib.h"
int add(int x, int y) { return x + y; }
; lib.def
LIBRARY dllTest
EXPORTS
add @1
LIBRARY 指定 DLL 名稱(影響導入庫生成)。EXPORTS 列出導出符號,@n 指定序號(序號調用更快、體積更小)。; 開頭,不可與語句同行。dllTest.lib(導入庫)。// dllCall.cpp
#include
#include "..\dllTest\lib.h" // 含 __declspec(dllimport) 聲明
#pragma comment(lib, "..\Debug\dllTest.lib")
int main() {
printf("%d", add(2, 3)); // 直接調用
return 0;
}
#include
#include
typedef int (*LPADD)(int, int); // 函數指針類型
int main() {
HINSTANCE hDll = LoadLibrary("dllTest.dll");
if (!hDll) return 1;
LPADD pAdd = (LPADD)GetProcAddress(hDll, "add"); // 或 GetProcAddress(hDll, (LPCSTR)1) 按序號
if (pAdd) printf("%d", pAdd(2, 3));
FreeLibrary(hDll);
return 0;
}
優點:DLL 路徑可配置、缺失不會導致進程啟動失敗、支援插件熱插拔。
.def 中指定 add @1,調用時 GetProcAddress(hDll, (LPCSTR)1)。
優點:導出表更小、無符號名洩露、調用略快。
缺點:維護序號映射表麻煩、重構易出錯。
__declspec(dllexport) 或列在 .def,供外部調用。static 或匿名命名空間限制作用域)。F11 進入 DLL。| 場景 | 推薦方式 |
|---|---|
| 固定依賴、追求簡潔 | 隱式鏈接 + __declspec(dllexport) |
| 插件架構、可選功能、多版本共存 | 顯式 LoadLibrary/GetProcAddress |
| 極度敏感體積、導出函數固定少量 | .def + 序號調用 |
非 MFC DLL 是跨語言、跨編譯器二進制複用的基石,掌握三種調用模式與導出聲明細節,能應對從簡單工具庫到複雜插件系統的各種場景。