動態鏈接庫(DLL)是 Windows 平台代碼復用與模塊化的基石。本文基於 Visual Studio 2010,從零構建 DLL,逐步講解顯式/隱式調用、導出函數/類/變量、裝飾名處理、DEF 文件與 `__declspec` 對比,最終實現跨 DLL 的 C++ 類導出與客戶端調用。
#include <objbase.h>
#include <iostream>
using namespace std;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) {
static HANDLE g_hModule;
switch (dwReason) {
case DLL_PROCESS_ATTACH:
cout << "Dll is attached!" << endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
cout << "Dll is detached!" << endl;
g_hModule = NULL;
break;
}
return TRUE;
}
項目屬性 → 配置類型 選 **動態庫 (.dll)**。生成即得 DLL。
客戶端動態加載 DLL,通過函數指針調用導出函數。適合非 C/C++ 語言調用或插件架構。
// 客戶端
typedef void (*DLL_FUNC)();
HINSTANCE hinst = LoadLibrary(L"dll_nolib.dll");
if (hinst) {
DLL_FUNC pf = (DLL_FUNC)GetProcAddress(hinst, "FuncInDll");
if (pf) pf();
}
LIBRARY dll_def.dll
EXPORTS
FuncInDll @1 PRIVATE
__declspec(dllexport) void FuncInDll();
⚠️ C++ 編譯器會修改函數名(Name Mangling),導致 `GetProcAddress` 需裝飾名。解決方案:加 `extern "C"` 強制 C 風格命名:
extern "C" __declspec(dllexport) void FuncInDll();
DLL 端導出時生成同名 `.lib` 導入庫。客戶端:
#include "dll_withlibAndH.h"
#pragma comment(lib, "dll_withLibAndH.lib")
int main() { FuncInDll(); return 0; }
// dll2.h #ifdef DLL_DLL2_EXPORTS #define DLL_DLL2_API __declspec(dllexport) #else #define DLL_DLL2_API __declspec(dllimport) #endif DLL_DLL2_API void FuncInDll2(void); DLL_DLL2_API void FuncInDll2(int); // 重載函數
DLL 端定義 `DLL_DLL2_EXPORTS` 宏,客戶端不定義,同一頭文件自動切換導出/導入聲明。完美支持 C++ 重載、類、全局變量導出。
class DLL_OBJECT_API CDll_Object {
public:
CDll_Object(); void show();
};
DLL_OBJECT_API int g_nDll = 9;
客戶端直接 `CDll_Object obj; obj.show();` 及訪問 `g_nDll`,無縫體驗。
本文整理自 “三人乘虎” 博客,原文鏈接:https://darhx.blog.51cto.com/7920146/1298950