Delphi以其獨特的面向控件的開發方式
強大的數據庫功能以及快速的編譯技術
使得它自發布起即格外引人注意
隨著Delphi
提供豐富的Internet應用
Delphi日益成為最重要的軟件開發工具之一
它吸引了許多原Visual Basic
Foxpro
dBase甚至C++的程序員
而這些程序員使用Delphi時需要解決的一個重要問題就是怎樣利用他們原有的代碼
本文將介紹Delphi與C++程序集成的方法
包括:
Delphi與C++之間函數的共享;
代碼的靜態鏈接和動態鏈接;
對象的共享
函數的共享在Delphi中調用C++函數與C++調用Delphi函數相當直接
需要注意的是
Delphi
默認的
函數調用方式是Pascal方式
Delphi
Delphi
的默認方式則是優化的cdecl調用方式
即register方式
要在C++與Delphi程序之間實現函數共享
除非有充分的原因
否則應該使用標准系統調用方式
即stdcall方式
為了使C++編譯器不將函數標記為
mang led
使Delphi編譯器誤認為函數是采用cdecl調用方式
應該在C++代碼中
以extern
C
說明被共享的函數
如下例所示:
原型說明:
在C++中:
extern
C
int _stdcall TestFunc();
在Delphi中:
function TestFunc:integer; stdcall;
調用語法:
在C++中:
int i=TestFunc();
在Delphi中:
var i:integer;
…
begin
…
i:=TestFunc;
…
end;
共享函數的參數必須是兩種語言都支持的變量類型
這是正確傳遞參數的前提
諸如Delphi的currency
string
set等變量類型
在C++中沒有相對應的變量類型
不能被用作共享函數的參數
可以用PChar類型以值參的方式傳遞字符串指針
這時用戶必須注意字符串空間的回收
Delphi語言中的變參應被說明成C++中相應變量類型的引用形式
如下:
在Delphi中:
function TestFunc(var i:integer):integer;
在C++中:
int TestFunc(int &i);
代碼鏈接
在Delphi與C++之間實現代碼鏈接可采用靜態鏈接或動態鏈接的方式
靜態鏈接方式
如果C++程序本身的代碼量很小
而且無需擔心與C運行庫會有交互過程
一般可選用靜態鏈接方式
即把Delphi與C++的目標文件(*
OBJ)鏈接成最終的可執行文件
具體的方法是使用{$L}編譯指令
使Delphi編譯器自動讀取指定目標文件
說明如下:
function TestFunc:integer;stdcall;
{$L TestFunc
OBJ}
動態鏈接方式
如果C++代碼已經相當全面或自成一個完整的子系統
代碼量很大
或者用到了C運行庫
在這種情況下
應該使用動態鏈接庫(DLL)的方式
此時
在兩種語言的源代碼中應做如下說明:
在C++中:
int stdcall export TestFunc();
在Delphi中:
function TestFunc:integer; stdcall;
external
TestFunc
DLL
;
對象的共享在C++與Delphi之間的對象共享主要體現在對象方法(Method)的共享方面
這種共享可分為兩個層次:對象(Object)級共享與類(Class)級共享
要實現對象級共享
程序設計語言需具備兩個前提條件:
能夠定義指向由另一語言創建的對象的指針;
可以訪問由指針確定的對象中的方法
要實現類級的共享
則還需考慮:
能夠創建由另一種語言定義的類的實例;
可以從堆中釋放一個實例所占用的空間;
派生新的類
以下介紹在Delphi與Borland C++之間實現對象共享的方法
C++共享Delphi對象
要實現從C++調用Delphi對象
首先要在Delphi單元的接口部分以及C++的頭文件中說明需要共享的對象的接口
在對象接口中定義該對象包含哪些屬性與方法
並說明可供共享的部分
對象的共享
關鍵在於方法的共享
在Delphi語言中
要使一個對象可以被共享
可以把它說明為兩個接口部分
暫稱為
共享接口
與
實現接口
其中共享接口指明對象中哪些方法可被另一種語言所共享;實現接口則繼承共享接口
並且在單元實現部分針對實現接口中的方法定義具體的實現
要定義一個可供C++共享的Delphi對象
共享接口的說明應注意:
在Delphi程序裡
要共享的方法必須被說明為抽象(abstract)
而且虛擬(virtual );
在C++程序裡
必須用關鍵字
virtual
及
=
後綴
把從Delphi共享的方法說明成
pure virtual
;
共享的對象方法必須在兩種語言裡都被說明成相同的調用方式
通常使用標准系統調用方式(stdcall)
下面
舉例說明這些規則
假設有這樣的一個Delphi對象:
TTestObject=class
procedure Proc
(x:integer);
function Func
(x:integer):PChar;
procedure Proc
;
function Func
:integer;
end;
如果C++程序需要共享其中的方法Proc
Func
可把上述說明修改成以下形式:
STestObject=class
procedure Proc
(x:integer); virtual; abstract; stdcall;
function Func
(x:integer); virtual; abstract; stdcall;
end;
TTestObject=class(STestObject)
procedure Proc
(x:integer);
fuction Func
(x:integer):PChar;
procedure Proc
;
fuction Func
:integer;
end;
在C++程序中做如下對象原型說明:
class STestObject {
virtual void Proc
(int x)=
;
virtual char *Func
(int x)=
;
};
為了能在C++中成功地訪問Delphi定義的類
Delphi接口說明時必須包含一個可共享的
制造函數(Factory Function)
CreateTestObject
該制造函數可被定義在動態鏈接庫或目標文件(
OBJ)中
例如:
Library TestLib;
exports CreateTestObject;
function CreateTestObject:STestObject; stdcall;
begin
Result:=TTestObject
Create;
end;
…
end
經過這樣的處理
現在可在C++程序中使用這個由Delphi定義的對象
調用方式如下:
extern
C
STestObject stdcall *CreateTestObject();
void UseTestObject(void) {
STestObject *theTestObject=CreateTestObject();
theTestObject
>Proc
(
);
Char *str=theTestObject
>Func
(
);
}
當調用制造函數CreateTestObject時
實際上已經在Delphi一側占用了一個對象實例的空間
C++程序在針對該對象的所有處理完成後必須考慮釋放這一空間
具體的實現可在Delphi中定義一個類
如上述Proc
的共享方法Free
以此來完成這一任務:
STestObject=class
procedure Proc
(x:integer); virtual; abstract; stdcall;
function Func
(x:integer); virtual; abstract; stdcall;
procedure Free; virtual; abstract; stdcall;
end;
…
implementation
…
procedure TTestObject
Free;
begin
…
end;
…
end
Delphi共享C++對象
通常
程序員會考慮使用Delphi來編制用戶界面
所以Delphi代碼調用C++代碼似乎顯得更加實際些
其實
Delphi共享C++對象的實現方法與上述C++共享Delphi對象非常相似
用同樣的共享接口與實現接口說明方法來定義C++的類:
class STestObjedt {
virtual void Proc
(int x)=
;
virtual char *Func
(int x)=
;
};
class TTestObjedt :public STestObject {
void Proc
(int x);
char *Func
(int x);
void Proc
();
int Func
();
void Free();
};
然後實現這些方法
同樣地
C++對象需要一個與之對應的制造函數
這裡以DLL為例
STestObject stdcall export *CreateTestObject() {
return (STestObject *) new TTestObject
Create;
}
Delphi代碼可以通過調用制造函數CreateTestObject
很容易地在C++中創建實例
獲得指向該實例的指針值
並以這個指針值來調用對象中的共享方法
當然
在進行完該對象的相關處理後
千萬不要忘了調用Free釋放占用的空間
From:http://tw.wingwit.com/Article/program/Delphi/201311/24678.html