Delphi与C++之间通过实现函数与对象共享

2016-02-19 12:50 36 1 收藏

下面,图老师小编带您去了解一下Delphi与C++之间通过实现函数与对象共享,生活就是不断的发现新事物,get新技能~

【 tulaoshi.com - 编程语言 】

  实在说,我对delphi的理解不是很深入,使用它写过一些小程序,不过鉴于borland的传奇,还是看了李维那本vcl内幕剖析,最终的感觉不是对delphi多么狂热,反而是另样的深入理解了c++的优缺点以及模式设计一些理念的深化,不过,仍旧对borland抱有尊敬,另外也羡慕那些使用delphi的人,控间好多啊,:)这个是我早期从bbs上收集的文章,暂且贴在这里,算是开门大吉

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  Delphi以其独特的面向控件的开发方式、强大的数据库功能以及快速的编译技术,使得它自发布起即格外引人注意。随着Delphi 3提供丰富的Internet应用,Delphi日益成为最重要的软件开发工具之一,它吸引了许多原Visual Basic、Foxpro、dBase甚至C++的程序员,而这些程序员使用Delphi时需要解决的一个重要问题就是怎样利用他们原有的代码。本文将介绍Delphi与C++程序集成的方法,包括:
  Delphi与C++之间函数的共享;
  代码的静态链接和动态链接;
  对象的共享。

  
  函数的共享在Delphi中调用C++函数与C++调用Delphi函数相当直接,需要注意的是,Delphi 1默认的
  函数调用方式是Pascal方式,Delphi 2、Delphi 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++中没有相对应的变量类型,不能被用作共享函数的参数。可以用PChar类型以值参的方式传递字符串指针,这时用户必须注意字符串空间的回收。
  Delphi语言中的变参应被说明成C++中相应变量类型的引用形式,如下:

  在Delphi中:
  function TestFunc(var i:integer):integer;
  在C++中:
  int TestFunc(int &i);
  代码链接
  在Delphi与C++之间实现代码链接可采用静态链接或动态链接的方式。

  
  1.静态链接方式
  如果C++程序本身的代码量很小,而且无需担心与C运行库会有交互过程,一般可选用静态链接方式,即把Delphi与C++的目标文件(*.OBJ)链接成最终的可执行文件。具体的方法是使用{$L}编译指令,使Delphi编译器自动读取指定目标文件,说明如下:
  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)级共享。要实现对象级共享,程序设计语言需具备两个前提条件:
  能够定义指向由另一语言创建的对象的指针;

  可以访问由指针确定的对象中的方法。

  要实现类级的共享,则还需考虑:
  能够创建由另一种语言定义的类的实例;
  可以从堆中释放一个实例所占用的空间;
  派生新的类。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  
  以下介绍在Delphi与Borland C++之间实现对象共享的方法。

  
  1.C++共享Delphi对象
  要实现从C++调用Delphi对象,首先要在Delphi单元的接口部分以及C++的头文件中说明需要共享的对象的接口,在对象接口中定义该对象包含哪些属性与方法,并说明可供共享的部分。对象的共享,关键在于方法的共享。在Delphi语言中,要使一个对象可以被共享,可以把它说明为两个接口部分,暂称为"共享接口"与"实现接口"。其中共享接口指明对象中哪些方法可被另一种语言所共享;实现接口则继承共享接口,并且在单元实现部分针对实现接口中的方法定义具体的实现。要定义一个可供C++共享的Delphi对象,共享接口的说明应注意:
    在Delphi程序里,要共享的方法必须被说明为抽象(abstract),而且虚拟(virtual );
    在C++程序里,必须用关键字"virtual"及"=0"后缀,把从Delphi共享的方法说明成"pure virtual";
    共享的对象方法必须在两种语言里都被说明成相同的调用方式,通常使用标准系统调用
方式(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)"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-Proc1(10);
  Char *str=theTestObject-Func1(0);
  }
  当调用制造函数CreateTestObject时,实际上已经在Delphi一侧占用了一个对象实例的空间,C++程序在针对该对象的所有处理完成后必须考虑释放这一空间,具体的实现可在Del
phi中定义一个类,如上述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释放占用的空间。

来源:http://www.tulaoshi.com/n/20160219/1602143.html

延伸阅读
标签: Web开发
一,简介 如果你对Unix/Linux有所了解的话,你应该知道他们大都自带了C和C++的编译器,分别是GCC和G++。Unix在程序安装及Make等许多地方使用到了这些编译器。利用一些控制台命令,C++和PHP, 我将向你介绍怎样生成一个完整的C++程序例子,他可以在用PHP程序来执行,并能获得相应的输出结果。我将先生成C++程序代码,并编译它,谈后讨论...
C++对象计数 作者:yy2better 关键字:C++ 对象计数 实例计数 本文目的是实现一个实用的对C++类计数的类,同时在实现过程中指出一些容易为人忽视的C++知识。 要实现一个类的对象(实例)计数,即程序运行中此类有多少个对象存在,最容易的实现方法是使用静态数据成员。如...
  类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容会觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持面向对象的,其实不然, !-- frame contents -- !-- /frame contents -- Visual BASIC 6.0 是典型的非面向对象的开发语言,但是它的确是支持类,支...
在没有讲述本章内容之前假如我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? 这个问题便是本章的重点: !-- frame contents -- !-- /frame contents -- 声明为static的类成员或者成员函数便能在类的范围内共同享,我们...
标签: Delphi
  一、VBA代码含义   Microsoft Word是一个集成化环境,是美国微软公司的字处理系统,但是它决不仅仅是一个字处理系统,它集成了Microsoft Visual Basic,可以通过编程来实现对Word功能的扩展。     Microsoft Visual Basic在word中的代码即Word的宏,通过编写Word宏,可实现一些文档处理的自动化,如实现文档的自...

经验教程

700

收藏

18
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部