首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Visual Studio 中 C++ DLL 創建與調用完整指南:靜態鏈接與動態加載

     編輯:關於C語言

什麼是 DLL?

動態鏈接庫包含可被多個程式同時使用的代碼與數據,促進代碼復用、減少內存佔用、簡化部署。Windows 系統大量使用 DLL(如 Comdlg32.dll 提供通用對話框)。

為何選擇 DLL(二進制復用)?

白盒復用(源碼)黑盒復用(DLL)
源碼暴露隱藏實現細節
多份拷貝浪費存儲單一文件共享
易發生命名衝突獨立命名空間
更新困難替換 DLL 即可升級

DLL 優勢

  1. 資源共享:多進程映射同一物理內存頁
  2. 模塊化架構:清晰邊界,便於團隊協作
  3. 部署簡單:只需分發 DLL 與導入庫

創建 DLL 實戰

1. 新建專案

VS 2012 → File → New → Project → Visual C++ → Win32 Project,名稱 DLLDemo1,應用程式類型選 DLL,勾選 Export symbols。

新建 DLL 專案

DLL 精靈設定

2. 導出函數聲明

MyCode.h

#ifndef _MYCODE_H_
#define _MYCODE_H_

#ifdef DLLDemo1_EXPORTS
#define EXPORTS_DEMO __declspec(dllexport)
#else
#define EXPORTS_DEMO __declspec(dllimport)
#endif

extern "C" EXPORTS_DEMO int Add(int a, int b);

#endif

3. 實現函數

MyCode.cpp

#include "stdafx.h"
#include "MyCode.h"

int Add(int a, int b) {
    return a + b;
}

4. 編譯生成

Build 專案,輸出目錄下得到 DLLDemo1.dll、DLLDemo1.lib、DLLDemo1.h。

調用 DLL 兩大方式

方式一:加載時動態鏈接(隱式鏈接)

編譯期鏈接 .lib,運行期自動加載 DLL,調用如同本地函數。

#include <windows.h>
#include <iostream>
#include "MyCode.h"
#pragma comment(lib, "..\\Debug\\DLLDemo1.lib")

using namespace std;

int main() {
    cout << Add(2, 3) << endl;  // 直接調用
    return 0;
}

方式二:運行時動態鏈接(顯式加載)

使用 LoadLibrary / GetProcAddress / FreeLibrary,無需 .lib,靈活控制加載時機。

#include <windows.h>
#include <iostream>
using namespace std;

typedef int (*AddFunc)(int, int);

int main() {
    HMODULE hDll = LoadLibrary("DLLDemo1.dll");
    if (hDll) {
        AddFunc add = (AddFunc)GetProcAddress(hDll, "Add");
        if (add) {
            cout << add(2, 3) << endl;
        }
        FreeLibrary(hDll);
    }
    return 0;
}

選型建議

場景推薦方式
啟動性能敏感運行時動態鏈接(延遲加載)
調用簡便、固定依賴加載時動態鏈接
需根據條件加載不同版本運行時動態鏈接

.def 文件導出替代方案

無需 __declspec(dllexport),通過模塊定義文件導出:

; MyCode.def
LIBRARY "DLLDemo2"
EXPORTS
    Add @1

調用時使用序號:

AddFunc add = (AddFunc)GetProcAddress(hDll, MAKEINTRESOURCE(1));

DllMain 入口函數詳解

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason, LPVOID lpReserved) {
    switch (ul_reason) {
        case DLL_PROCESS_ATTACH:  // 進程加載 DLL
            // 初始化,禁用線程通知優化
            DisableThreadLibraryCalls(hModule);
            break;
        case DLL_THREAD_ATTACH:   // 線程創建(若未禁用)
            break;
        case DLL_THREAD_DETACH:   // 線程結束
            break;
        case DLL_PROCESS_DETACH:  // 進程卸載 DLL
            // 清理資源
            break;
    }
    return TRUE;
}
  • 系統自動調用,不可手動調用
  • 若無 DllMain,系統提供空實現
  • DLL_PROCESS_DETACH 不會在 TerminateProcess 時調用,可能導致資源洩漏

總結

掌握 DLL 創建、兩種調用方式、.def 導出、DllMain 生命周期,即可在 C++ 專案中靈活實現模塊化、插件化架構。現代開發中更推薦使用 CMake 管理跨平台 DLL 構建,並配合版本資源、數字簽名進行發布。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved