熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

Delphi與C++之間通過實現函數與對象共享

2013-11-23 17:29:45  來源: Delphi編程 
Delphi以其獨特的面向控件的開發方式強大的數據庫功能以及快速的編譯技術使得它自發布起即格外引人注意隨著Delphi 提供豐富的Internet應用Delphi日益成為最重要的軟件開發工具之一它吸引了許多原Visual BasicFoxprodBase甚至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的currencystringset等變量類型在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 TestFuncOBJ}
  
  動態鏈接方式
  如果C++代碼已經相當全面或自成一個完整的子系統代碼量很大或者用到了C運行庫在這種情況下應該使用動態鏈接庫(DLL)的方式此時在兩種語言的源代碼中應做如下說明:
  在C++中:
  int stdcall export TestFunc();
  在Delphi中:
  function TestFunc:integer; stdcall;
  external TestFuncDLL;
  對象的共享在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++程序需要共享其中的方法ProcFunc可把上述說明修改成以下形式:
  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:=TTestObjectCreate;
  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 TTestObjectFree;
  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 TTestObjectCreate;
  }
  Delphi代碼可以通過調用制造函數CreateTestObject很容易地在C++中創建實例獲得指向該實例的指針值並以這個指針值來調用對象中的共享方法當然在進行完該對象的相關處理後千萬不要忘了調用Free釋放占用的空間
From:http://tw.wingwit.com/Article/program/Delphi/201311/24678.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.