C++Builder 雖提供視覺化開發,但早期控制元件匱乏,且版本間相容性差。Delphi 擁有豐富的 VCL 元件庫,如何在 C++Builder 中複用?本文介紹一種基於 DLL 的動態呼叫方案,適用於非視覺 VCL 元件的跨語言複用。
利用 Windows DLL 機制,將 Delphi VCL 元件封裝為 DLL 導出函數,C++Builder 透過 LoadLibrary/GetProcAddress 或靜態連結 LIB 動態呼叫。關鍵在於解決 VCL 元件建構函數需 TComponent 擁有者的問題。
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 元件的 OwnerTemp1,設置 ExitProc 確保卸載時正確釋放stdcall 呼叫慣例,確保跨語言相容// 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 邊界較困難 |
.pas 直接加入專案DLL 封裝法為早期 C++Builder 專案快速複用 Delphi 非視覺邏輯元件提供了務實路徑。雖非銀彈,但在遷移期專案中極具價值。現代開發建議優先考慮原生 C++ 實作或跨平台框架。