首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ DLL 匯出類方法調用:解決 LNK2019 未解析外部符號錯誤

     編輯:程式設計疑難解答

錯誤現象

主程式呼叫 DLL 匯出工廠函式取得類實例指標,調用成員函式時連結器報錯:unresolved external symbol "public: void __thiscall ClassA::M(void)"。

根本原因

  • ClassA::M() 定義在 DLL 內部,但類定義本身未匯出。
  • 主程式包含標頭檔看到類定義,編譯通過;連結階段找不到成員函式實體碼(在 DLL 中),且 DLL 未匯出該符號。
  • extern "C" 僅適用於自由函式,C++ 類成員函式有 Name Mangling,無法直接用 GetProcAddress 取得。

方案一:匯出整個類 (推薦,Windows/MSVC)

標頭檔:

#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

class DLL_API ClassA {
public:
    void M();
};

DLL 專案定義 DLL_EXPORTS 巨集。主程式直接 #include 標頭檔,連結 .lib 匯入庫,像呼叫本地類一樣使用:

ClassA obj; // 或 new ClassA
obj.M();

方案二:純 C 風格介面 (跨編譯器/語言)

DLL 僅匯出 extern "C" 自由函式,隱藏 C++ 類細節:

// DLL 標頭檔
#ifdef __cplusplus
extern "C" {
#endif

typedef struct ClassA_Opaque* ClassA_Handle;

__declspec(dllexport) ClassA_Handle ClassA_Create();
__declspec(dllexport) void ClassA_M(ClassA_Handle h);
__declspec(dllexport) void ClassA_Destroy(ClassA_Handle h);

#ifdef __cplusplus
}
#endif

DLL 實現:

// DLL cpp
struct ClassA_Opaque { void M() { cout << "I am invoked."; } };

extern "C" {
    __declspec(dllexport) ClassA_Handle ClassA_Create() { return new ClassA_Opaque; }
    __declspec(dllexport) void ClassA_M(ClassA_Handle h) { static_cast<ClassA_Opaque*>(h)->M(); }
    __declspec(dllexport) void ClassA_Destroy(ClassA_Handle h) { delete static_cast<ClassA_Opaque*>(h); }
}

主程式動態載入:

auto hmod = LoadLibrary("DllProj.dll");
auto create = (ClassA_Handle(*)())GetProcAddress(hmod, "ClassA_Create");
auto callM = (void(*)(ClassA_Handle))GetProcAddress(hmod, "ClassA_M");
auto destroy = (void(*)(ClassA_Handle))GetProcAddress(hmod, "ClassA_Destroy");

ClassA_Handle h = create();
callM(h);
destroy(h);
FreeLibrary(hmod);

關鍵提醒

  • DLL 與主程式必須使用相同編譯器版本、相同 CRT 連結方式 (MD/MT),否則記憶體管理、異常處理、STL 佈局不一致會導致崩潰。
  • 跨語言/編譯器場景強制使用方案二 (C 介面 + 不透明指標)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved