VC的對象傳遞給DELPHI使用

在VC中的DLL類導出以後完全是可以被delphi調用的.
調用方法及說明如下:
Delphi調用VC++類的方法:  
    1、在VC++的頭文件中說明類,注意,定義等類方法  
        最後一個爲析構函數;  
          倒數第二個是建構方法;
 
        定義公開的方法:virtual   void   _stdcall   Free(),該方法將調用析構函數  
          其他所有方法均定義爲:virtual   、_stdcall;  
        不要定義常數屬性,實現屬性的方法、函數也要定義爲virtual   、_stdcall;  
    2、在.cpp文件中:  
        實現類的方法,注意Free()的實現,要調用析構函數;  
        增加一個獨立的函數:CreateObject,函數內部調用類的建構方法,返回類的句柄,;  
        在.cpp文件的結尾出輸出CreateObject函數:  
                    extern   "C"   __declspec(dllexport)   CCreateObject   CreateObject(......)  

    3、在Delphi程序中,重新定義類CCreateObject,  
        要完全按照在VC++中類的方法排列次序逐一說明,所有方法都定義爲:Virtual;StdCall;Abstract;  
        定義新的建構方法  
                  Class   Function   Create   CCreateObject;  
        說明函數類型:  
                  Type   CCreateObject=Function(......);   Cdecl;     //函數類型  
        定義函數變量:  
                  Var   CreateObject:     CCreateObject;  
        CCreateObject.Create的實現,只需要一句話:  
                    Result:=CreateObject  
                  其中CreateObject就是從VC++的DLL中導出的建立CCreateObject實例的函數。  
    4、在Delphi程序中,可以動態連接VC++的Dll庫:  
          DLL_Handle:=LoadLibrary(PChar(DLLPath));  
          DLL_Handle>0   Then                                                                   //若加載成功,  
            Begin                                                                                         //則定位函數  
                Try  
                    @CreateObject:=GetProcAddress(DLL_Handle,CreateObject);  
                Except  
                    FreeLibrary(DLL_Handle);  
                End  
            End  
    5、使用:  
          創建實例:AInst:=CCreateObject.Create(......);  
          調用方法:AInst.Method......       與Delphi內定義的類一樣處理。  
   
      注意:  
        1、實現的方法爲Delphi的虛擬表方法;  
        2、在沒有建立實例前,類方法也不能使用,因爲類方法也只能通過實例才能映射過來,這與本地說明的類不一樣;  
        3、一定要特別注意兩邊方法的對應關係;  
        4、在Delphi這邊,同樣也不能定義直接取或設置值的屬性,必須用函數和方法實現,且實現的函數或方法一定要在VC++的類定義中定義.
LiuWeiBin 17:50:54
  注意:
在delphi定義類的時候,一定要注意 procedure myMax(const x,y:Integer; var z:Integer);virtual ;stdcall; abstract;後面的virtual ;stdcall; abstract;順序.

 

 

 

 

 

Delphi以其獨特的面向控件的開發方式、強大的數據庫功能以及
快速的編譯技術,使得它自發布起即格外引人注意。隨着Delphi 3提
供豐富的Internet應用,Delphi日益成爲最重要的軟件開發工具之一,
它吸引了許多原Visual Basic、Foxpro、dBase甚至C++的程序員,而
這些程序員使用Delphi時需要解決的一個重要問題就是怎樣利用他們
原有的代碼。本文將介紹Delphi與C++程序集成的方法,包括:
S Delphi與C++之間函數的共享;
S 代碼的靜態鏈接和動態鏈接;
S 對象的共享。
函數的共享
在Delphi中調用C++函數與C++調用Delphi函數相當直接,需要注
意的是,Delphi 1默認的函數調用方式是Pascal方式,Delphi 2、Delp
hi 3的默認方式則是優化的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++中沒有相對應的變量類型,不能被用作共享函數的參數。可以用PC
har類型以值參的方式傳遞字符串指針,這時用戶必須注意字符串空間
的回收。
Delphi語言中的變參應被說明成C++中相應變量類型的引用形式,
如下:
在Delphi中:
function TestFunc(var i:integer):integer;
在C++中:
int TestFunc(int &i);
代碼鏈接
在Delphi與C++之間實現代碼鏈接可採用靜態鏈接或動態鏈接的
方式。
1.靜態鏈接方式
如果C++程序本身的代碼量很小,而且無需擔心與C運行庫會有交
互過程,一般可選用靜態鏈接方式,即把Delphi與C++的目標文件(*.OB
J)鏈接成最終的可執行文件。具體的方法是使用{$L}編譯指令,使Del
phi編譯器自動讀取指定目標文件,說明如下:
function TestFunc:integer;stdcall;
{$L TestFunc.OBJ}
2.動態鏈接方式
如果C++代碼已經相當全面或自成一個完整的子系統,代碼量很大
,或者用到了C運行庫,在這種情況下,應該使用動態鏈接庫(DLL)的方
式。此時,在兩種語言的源代碼中應做如下說明:
在C++中:
int stdcall export TestFunc();
在Delphi中:
function TestFunc:integer; stdcall;
external ‘TestFunc.DLL’;
對象的共享
在C++與Delphi之間的對象共享主要體現在對象方法(Method)的
共享方面,這種共享可分爲兩個層次:對象(Object)級共享與類(Class
)級共享。
要實現對象級共享,程序設計語言需具備兩個前提條件:
S 能夠定義指向由另一語言創建的對象的指針;
S 可以訪問由指針確定的對象中的方法。
要實現類級的共享,則還需考慮:
S 能夠創建由另一種語言定義的類的實例;
S 可以從堆中釋放一個實例所佔用的空間;
S 派生新的類。
以下介紹在Delphi與Borland C++之間實現對象共享的方法。
1.C++共享Delphi對象
要實現從C++調用Delphi對象,首先要在Delphi單元的接口部分以
及C++的頭文件中說明需要共享的對象的接口,在對象接口中定義該對
象包含哪些屬性與方法,並說明可供共享的部分。對象的共享,關鍵在
於方法的共享。在Delphi語言中,要使一個對象可以被共享,可以把它
說明爲兩個接口部分,暫稱爲"共享接口"與"實現接口"。其中共享接
口指明對象中哪些方法可被另一種語言所共享;實現接口則繼承共享
接口,並且在單元實現部分針對實現接口中的方法定義具體的實現。
要定義一個可供C++共享的Delphi對象,共享接口的說明應注意:
S 在Delphi程序裏,要共享的方法必須被說明爲抽象(abstract),
而且虛擬(virtual );
S 在C++程序裏,必須用關鍵字"virtual"及"=0"後綴,把從Delphi
共享的方法說明成"pure virtual";
S 共享的對象方法必須在兩種語言裏都被說明成相同的調用方式
,通常使用標準系統調用方式(stdcall)。
下面,舉例說明這些規則,假設有這樣的一個Delphi對象:
TTestObject=class
procedure Proc1(x:integer);
function Func1(x:integer):PChar;
procedure Proc2;
function Func2:integer;
end;
如果C++程序需要共享其中的方法Proc1、Func1,可把上述說明修
改成以下形式:
STestObject=class
procedure Proc1(x:integer); virtual; abstract; stdcall;
function Func1(x:integer); virtual; abstract; stdcall;
end;
TTestObject=class(STestObject)
procedure Proc1(x:integer);
fuction Func1(x:integer):PChar;
procedure Proc2;
fuction Func2:integer;
end;
在C++程序中做如下對象原型說明:
class STestObject {
virtual void Proc1(int x)=0;
virtual char *Func1(int x)=0;
};
爲了能在C++中成功地訪問Delphi定義的類, Delphi接口說明時
必須包含一個可共享的"製造函數(Factory Function)"CreateTestOb
ject,該製造函數可被定義在動態鏈接庫或目標文件(.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->Proc1(10);
Char *str=theTestObject->Func1(0);
}
當調用製造函數CreateTestObject時,實際上已經在Delphi一側
佔用了一個對象實例的空間,C++程序在針對該對象的所有處理完成後
必須考慮釋放這一空間,具體的實現可在Delphi中定義一個類,如上述
Proc1的共享方法Free,以此來完成這一任務:
STestObject=class
procedure Proc1(x:integer); virtual; abstract; stdcall;
function Func1(x:integer); virtual; abstract; stdcall;
procedure Free; virtual; abstract; stdcall;
end;

implementation

procedure TTestObject.Free;
begin

end;

end.
2.Delphi共享C++對象
通常,程序員會考慮使用Delphi來編制用戶界面,所以Delphi代碼
調用C++代碼似乎顯得更加實際些。其實,Delphi共享C++對象的實現
方法與上述C++共享Delphi對象非常相似。
用同樣的共享接口與實現接口說明方法來定義C++的類:
class STestObjedt {
virtual void Proc1(int x)=0;
virtual char *Func1(int x)=0;
};
class TTestObjedt :public STestObject {
void Proc1(int x);
char *Func1(int x);
void Proc2();
int Func2();
void Free();
};
然後實現這些方法。同樣地,C++對象需要一個與之對應的製造函
數,這裏以DLL爲例
STestObject stdcall export *CreateTestObject() {
return (STestObject *) new TTestObject.Create;
}
Delphi代碼可以通過調用製造函數CreateTestObject,很容易地
在C++中創建實例,獲得指向該實例的指針值,並以這個指針值來調用
對象中的共享方法。當然,在進行完該對象的相關處理後,千萬不要忘
了調用Free釋放佔用的空間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章