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

C++Builder DLL 開發完全手冊:建立、靜態/動態調用、導出類與函數

     編輯:VC 教學

一、建立 DLL 專案

  1. File → New → DLL Wizard,產生專案框架。
  2. 專案會包含 DllEntryPoint (進入點)、預設導出函數/類範例。

二、導出語法

1. 導出函數 (C 風格,支援動態載入)

extern "C" __declspec(dllexport) ReturnType __stdcall FuncName(Params);
  • extern "C":防止 C++ 名稱修飾,確保 GetProcAddress 能以原名找到。
  • __stdcall:Windows API 標準呼叫慣例,建議統一使用。

2. 導出類 (僅支援靜態連結)

class __declspec(dllexport) __stdcall MyDllClass {
public:
    MyDllClass();
    void CreateAForm();
    TForm* DllMyForm;
};
  • 類導出會匯出所有 public 成員函數、虛函數表、RTTI 等。
  • 調用端必須擁有完整類定義 (標頭檔) 並連結 import library (.lib)。

三、DLL 專案完整範例

// Dll.cpp
#include "DllForm.h"  // TDllFrm 定義
USERES("Dll.res");
USEFORM("DllForm.cpp", DllFrm);

class __declspec(dllexport) __stdcall MyDllClass {
public:
    MyDllClass() {}
    void CreateAForm() {
        DllMyForm = new TDllFrm(Application);
        DllMyForm->Show();
    }
    TDllFrm* DllMyForm;
};

TDllFrm* DllMyForm2;

extern "C" __declspec(dllexport) __stdcall void CreateFromFunct() {
    DllMyForm2 = new TDllFrm(Application);
    DllMyForm2->Show();
}

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) {
    return 1;  // 成功
}

四、靜態調用 (Load-time Dynamic Linking)

  1. 使用 implib.exe 產生 import library:
    implib MyDll.lib MyDll.dll
  2. 將 MyDll.lib 加入調用端專案 (Project → Add to Project)。
  3. 標頭檔宣告導入:
// Unit1.h
#include "DllForm.h"
__declspec(dllimport) class __stdcall MyDllClass {
public:
    MyDllClass();
    void CreateAForm();
    TDllFrm* DllMyForm;
};
extern "C" __declspec(dllimport) __stdcall void CreateFromFunct();
  1. 直接呼叫:
// Unit1.cpp
MyDllClass* DllClass = nullptr;

void __fastcall TForm1::Button1Click(TObject *Sender) {
    DllClass = new MyDllClass();  // 導出類必須靜態調用
    DllClass->CreateAForm();
}

void __fastcall TForm1::Button2Click(TObject *Sender) {
    CreateFromFunct();  // 導出函數
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) {
    delete DllClass;
}

五、動態調用 (Run-time Dynamic Linking)

適用於:無 .lib、延遲載入、條件載入、插件架構。

HINSTANCE hDll = LoadLibrary("MyDll.dll");
if (hDll) {
    // 導出函數
    typedef void (__stdcall *PFN_CREATE)();
    PFN_CREATE pCreate = (PFN_CREATE)GetProcAddress(hDll, "CreateFromFunct");
    if (pCreate) pCreate();

    // 導出類較複雜:需取得建構函數、成員函數位址,手動管理 this 指標
    // 建議改用「導出工廠函數回傳介面指標」模式

    FreeLibrary(hDll);
}

六、專案設定關鍵點

  • Packages 頁:取消勾選 Build with runtime packages。
  • Linker 頁:取消勾選 Use dynamic RTL。
  • 否則產生的 DLL 會依賴 vclxx.bpl、rtlxx.bpl 等執行套件,部署麻煩。

七、常見問題與技巧

  • 跨模組 new/delete:DLL 與 EXE 必須使用相同記憶體管理器。若關閉 dynamic RTL,各自擁有獨立堆疊,嚴禁跨模組刪除記憶體。解決:DLL 提供 DestroyObject 導出函數,或共用 borlndmm.dll (啟用 dynamic RTL 並部署)。
  • implib 產生的 .lib 僅含導出符號表,無程式碼。
  • tdump -ee MyDll.dll 或 dumpbin /exports 可檢視導出符號。
  • 導出類名稱修飾極複雜,跨編譯器 (BCB ↔ MSVC) 導出類不可行,跨語言請使用 C 風格導出函數 + 介面 (COM) 或純 C API。

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