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释放占用的空间。

在Delphi与C++之间实现函数与对象共享
Reply content :
Photo link :
默认共享是Windows 2000提供的功能,是为了实现远程协助和管理而设的。 您可以使用如下两种办法来取消Windows2000提供的默认共享逻辑驱动器服务(drive letter$w),并使其在开机后不会自动产生…  Details
如果一个DTD适用于多份文档,就不能总把它放在应用它的每份文档的同一目录下。可以使用URL来准确指明DTD的地址。例如,让我们假设棒球DTD在http://metalab.unc.edu/xml/dtds/baseball.dtd,可在序言…  Details
许多宽带提供商都对用户设置了MAC地址绑定的功能,主要是为了限制用户通过共享实现多台计算机同时接入互联网。由于每块网卡的MAC地址都是固定的,经过地址绑定后,IP地址与计算机或…  Details
可以在Windows 2000系统的恢复控制台中,用命令“Net use”来完成。具体的使用方法是: Net use [ ComputerNameShareName [/user:[DomainName] UserName] password] |[driveletter:] [/d] 其中,servernameshare…  Details
在Windows 98中,可以用注册表编辑器查看所使用的序列号,但是到了Windows XP时代,注册表中只能查到PID号。面对这种情况,我们有两处办法可以采取:     一、Windows XP的激活文件位…  Details
问:我有两台电脑原来是使用网卡互联,后来把其中的一台电脑的网卡连接到宽带上,请问有哪些方法可以让另一台电脑也能连接到宽带上? 答:解决共享上网问题,比较传统的…  Details
在线发布的私人视频内容常常含有色情和暴力成分,这又给人们增加了新的担忧。在线视频共享网站的爆炸性增长已经成为摆在父母们和网站面前的最大难题,父母们要保护儿童…  Details
在房改售房中,有一些职工因种种原因或工资水平较低,自己无能力支付购房价款,又不愿意放弃优惠购房的机,会便与子女共同筹款购买。但购买后如何共享房屋产权,是家庭所有成员共同…  Details
前面的合法的例子都在文档的序言部分包含了DTD。但是XML真正的功能来自于不同的人们编写的可为许多文档共享通用的DTD。如果DTD不是直接包含在文档内,而是从外部联结而来,则DTD的改变…  Details
如果C盘被共享,即使是只读,带来的灾难也是巨大的。一台装有Windows 98系统的计算机可以被几个人用,不同的使用者通过键入自己的用户名和密码来登录系统。而这些机密的信息就是存储…  Details