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

在 C++Builder 中複用 Delphi VCL 控制元件:DLL 封裝法

     編輯:關於C++

C++Builder 雖提供視覺化開發,但早期控制元件匱乏,且版本間相容性差。Delphi 擁有豐富的 VCL 元件庫,如何在 C++Builder 中複用?本文介紹一種基於 DLL 的動態呼叫方案,適用於非視覺 VCL 元件的跨語言複用。

核心思路

利用 Windows DLL 機制,將 Delphi VCL 元件封裝為 DLL 導出函數,C++Builder 透過 LoadLibrary/GetProcAddress 或靜態連結 LIB 動態呼叫。關鍵在於解決 VCL 元件建構函數需 TComponent 擁有者的問題。

實作步驟

一、Delphi 端建立 DLL 專案

library SampleDLL;
uses SysUtils, Classes, Sample;

type
  TTempComp = class(TComponent)
  public
    constructor Create1; // 空建構函數,作為 Owner
  end;

var
  Sample1: TSample;      // 目標 VCL 元件
  SaveExit: Pointer;
  Temp1: TTempComp;

constructor TTempComp.Create1;
begin
  // 不呼叫 inherited Create,避免建立額外資源
end;

function OpenSample: Boolean; stdcall; export;
begin
  Sample1 := TSample.Create(Temp1); // 以 Temp1 為 Owner 建立
  Result := Sample1.Activated;
end;

procedure CloseSample; stdcall; export;
begin
  Sample1.Free;
end;

function GetActivated: Boolean; stdcall; export;
begin
  Result := Sample1.Activated;
end;

function GetPro1: Integer; stdcall; export;
begin
  Result := Sample1.Pro1;
end;

function GetPro2: Integer; stdcall; export;
begin
  Result := Sample1.Pro2;
end;

procedure LibExit; far;
begin
  if Sample1.Activated then Sample1.Free;
  ExitProc := SaveExit;
  Temp1.Free;
end;

exports
  OpenSample, CloseSample, GetActivated, GetPro1, GetPro2;

begin
  Temp1 := TTempComp.Create1;
  SaveExit := ExitProc;
  ExitProc := @LibExit;
end.

關鍵點解析

  • TTempComp 繼承 TComponent,提供空建構函數 Create1 作為 VCL 元件的 Owner
  • DLL 進入點建立 Temp1,設置 ExitProc 確保卸載時正確釋放
  • 所有導出函數採用 stdcall 呼叫慣例,確保跨語言相容

二、C++Builder 端呼叫

// 1. 使用 implib 由 DLL 產生 .lib,加入專案
// 2. 頭檔宣告
extern "C" __declspec(dllimport) bool __stdcall OpenSample(void);
extern "C" __declspec(dllimport) void __stdcall CloseSample(void);
extern "C" __declspec(dllimport) bool __stdcall GetActivated(void);
extern "C" __declspec(dllimport) int  __stdcall GetPro1(void);
extern "C" __declspec(dllimport) int  __stdcall GetPro2(void);

// 3. 使用
if (OpenSample()) {
    bool act = GetActivated();
    int p1 = GetPro1();
    int p2 = GetPro2();
    // ... 使用屬性值 ...
    CloseSample();
}

優缺點評析

優點缺點
非視覺元件完美複用視覺元件無法直接使用 (需 ActiveX/COM)
跨語言、跨版本相容性好需手動維護導出介面,介面變更需同步修改
不佔用 C++Builder 記憶體空間DLL 邊界頻繁呼叫有效能開銷
原始碼保護 (僅發布 DLL)調試跨 DLL 邊界較困難

替代方案簡述

  • ActiveX/COM:視覺元件首選,支援設計時拖放
  • C++Builder 6+ 直接編譯 Delphi 單元:新版本支援 .pas 直接加入專案
  • 原始碼轉寫:長期維護專案建議重寫為原生 C++ 元件

結語

DLL 封裝法為早期 C++Builder 專案快速複用 Delphi 非視覺邏輯元件提供了務實路徑。雖非銀彈,但在遷移期專案中極具價值。現代開發建議優先考慮原生 C++ 實作或跨平台框架。

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