⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 delphi_c.htm

📁 对于学习很有帮助
💻 HTM
字号:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>在Delphi与C++之间实现函数与对象共享</title>
</head>

<body bgcolor="#FFFFFF" text="#000000">

<p align="center"><strong><font size="5" color="#000000">在Delphi与C++之间实现函数与对象共享</font><font
color="#008000" size="5"><br>
</font></strong></p>

<p>Delphi以其独特的面向控件的开发方式、强大的数据库功能以及<br>
快速的编译技术,使得它自发布起即格外引人注意。随着Delphi 3提<br>
供丰富的Internet应用,Delphi日益成为最重要的软件开发工具之一,<br>
它吸引了许多原Visual Basic、Foxpro、dBase甚至C++的程序员,而<br>
这些程序员使用Delphi时需要解决的一个重要问题就是怎样利用他们<br>
原有的代码。本文将介绍Delphi与C++程序集成的方法,包括:<br>
S Delphi与C++之间函数的共享;<br>
S 代码的静态链接和动态链接;<br>
S 对象的共享。<br>
函数的共享<br>
在Delphi中调用C++函数与C++调用Delphi函数相当直接,需要注<br>
意的是,Delphi 1默认的函数调用方式是Pascal方式,Delphi 2、Delp<br>
hi 3的默认方式则是优化的cdecl调用方式,即register方式。要在C+<br>
+与Delphi程序之间实现函数共享,除非有充分的原因,否则应该使用<br>
标准系统调用方式,即stdcall方式。为了使C++编译器不将函数标记<br>
为&quot;mang led&quot;,使Delphi编译器误认为函数是采用cdecl调用方式,应<br>
该在C++代码中,以extern &quot;C &quot;说明被共享的函数,如下例所示:<br>
原型说明:<br>
在C++中:<br>
extern &quot;C&quot; int _stdcall TestFunc();<br>
在Delphi中:<br>
function TestFunc:integer; stdcall;<br>
调用语法:<br>
在C++中:<br>
int i=TestFunc();<br>
在Delphi中:<br>
var i:integer;<br>
…<br>
begin<br>
…<br>
i:=TestFunc;<br>
…<br>
end;<br>
共享函数的参数必须是两种语言都支持的变量类型,这是正确传<br>
递参数的前提。诸如Delphi的currency、string、set等变量类型,在<br>
C++中没有相对应的变量类型,不能被用作共享函数的参数。可以用PC<br>
har类型以值参的方式传递字符串指针,这时用户必须注意字符串空间<br>
的回收。<br>
Delphi语言中的变参应被说明成C++中相应变量类型的引用形式,<br>
如下:<br>
在Delphi中:<br>
function TestFunc(var i:integer):integer;<br>
在C++中:<br>
int TestFunc(int &amp;i);<br>
代码链接<br>
在Delphi与C++之间实现代码链接可采用静态链接或动态链接的<br>
方式。<br>
1.静态链接方式<br>
如果C++程序本身的代码量很小,而且无需担心与C运行库会有交<br>
互过程,一般可选用静态链接方式,即把Delphi与C++的目标文件(*.OB<br>
J)链接成最终的可执行文件。具体的方法是使用{$L}编译指令,使Del<br>
phi编译器自动读取指定目标文件,说明如下:<br>
function TestFunc:integer;stdcall;<br>
{$L TestFunc.OBJ}<br>
2.动态链接方式<br>
如果C++代码已经相当全面或自成一个完整的子系统,代码量很大<br>
,或者用到了C运行库,在这种情况下,应该使用动态链接库(DLL)的方<br>
式。此时,在两种语言的源代码中应做如下说明:<br>
在C++中:<br>
int stdcall export TestFunc();<br>
在Delphi中:<br>
function TestFunc:integer; stdcall;<br>
external ‘TestFunc.DLL’;<br>
对象的共享<br>
在C++与Delphi之间的对象共享主要体现在对象方法(Method)的<br>
共享方面,这种共享可分为两个层次:对象(Object)级共享与类(Class<br>
)级共享。<br>
要实现对象级共享,程序设计语言需具备两个前提条件:<br>
S 能够定义指向由另一语言创建的对象的指针;<br>
S 可以访问由指针确定的对象中的方法。<br>
要实现类级的共享,则还需考虑:<br>
S 能够创建由另一种语言定义的类的实例;<br>
S 可以从堆中释放一个实例所占用的空间;<br>
S 派生新的类。<br>
以下介绍在Delphi与Borland C++之间实现对象共享的方法。<br>
1.C++共享Delphi对象<br>
要实现从C++调用Delphi对象,首先要在Delphi单元的接口部分以<br>
及C++的头文件中说明需要共享的对象的接口,在对象接口中定义该对<br>
象包含哪些属性与方法,并说明可供共享的部分。对象的共享,关键在<br>
于方法的共享。在Delphi语言中,要使一个对象可以被共享,可以把它<br>
说明为两个接口部分,暂称为&quot;共享接口&quot;与&quot;实现接口&quot;。其中共享接<br>
口指明对象中哪些方法可被另一种语言所共享;实现接口则继承共享<br>
接口,并且在单元实现部分针对实现接口中的方法定义具体的实现。<br>
要定义一个可供C++共享的Delphi对象,共享接口的说明应注意:<br>
S 在Delphi程序里,要共享的方法必须被说明为抽象(abstract),<br>
而且虚拟(virtual );<br>
S 在C++程序里,必须用关键字&quot;virtual&quot;及&quot;=0&quot;后缀,把从Delphi<br>
共享的方法说明成&quot;pure virtual&quot;;<br>
S 共享的对象方法必须在两种语言里都被说明成相同的调用方式<br>
,通常使用标准系统调用方式(stdcall)。<br>
下面,举例说明这些规则,假设有这样的一个Delphi对象:<br>
TTestObject=class<br>
procedure Proc1(x:integer);<br>
function Func1(x:integer):PChar;<br>
procedure Proc2;<br>
function Func2:integer;<br>
end;<br>
如果C++程序需要共享其中的方法Proc1、Func1,可把上述说明修<br>
改成以下形式:<br>
STestObject=class<br>
procedure Proc1(x:integer); virtual; abstract; stdcall;<br>
function Func1(x:integer); virtual; abstract; stdcall;<br>
end;<br>
TTestObject=class(STestObject)<br>
procedure Proc1(x:integer);<br>
fuction Func1(x:integer):PChar;<br>
procedure Proc2;<br>
fuction Func2:integer;<br>
end;<br>
在C++程序中做如下对象原型说明:<br>
class STestObject {<br>
virtual void Proc1(int x)=0;<br>
virtual char *Func1(int x)=0;<br>
};<br>
为了能在C++中成功地访问Delphi定义的类, Delphi接口说明时<br>
必须包含一个可共享的&quot;制造函数(Factory Function)&quot;CreateTestOb<br>
ject,该制造函数可被定义在动态链接库或目标文件(.OBJ)中,例如:<br>
Library TestLib;<br>
exports CreateTestObject;<br>
function CreateTestObject:STestObject; stdcall;<br>
begin<br>
Result:=TTestObject.Create;<br>
end;<br>
…<br>
end.<br>
经过这样的处理,现在可在C++程序中使用这个由Delphi定义的对<br>
象,调用方式如下:<br>
extern &quot;C&quot; STestObject stdcall *CreateTestObject();<br>
void UseTestObject(void) {<br>
STestObject *theTestObject=CreateTestObject();<br>
theTestObject-&gt;Proc1(10);<br>
Char *str=theTestObject-&gt;Func1(0);<br>
}<br>
当调用制造函数CreateTestObject时,实际上已经在Delphi一侧<br>
占用了一个对象实例的空间,C++程序在针对该对象的所有处理完成后<br>
必须考虑释放这一空间,具体的实现可在Delphi中定义一个类,如上述<br>
Proc1的共享方法Free,以此来完成这一任务:<br>
STestObject=class<br>
procedure Proc1(x:integer); virtual; abstract; stdcall;<br>
function Func1(x:integer); virtual; abstract; stdcall;<br>
procedure Free; virtual; abstract; stdcall;<br>
end;<br>
…<br>
implementation<br>
…<br>
procedure TTestObject.Free;<br>
begin<br>
…<br>
end;<br>
…<br>
end.<br>
2.Delphi共享C++对象<br>
通常,程序员会考虑使用Delphi来编制用户界面,所以Delphi代码<br>
调用C++代码似乎显得更加实际些。其实,Delphi共享C++对象的实现<br>
方法与上述C++共享Delphi对象非常相似。<br>
用同样的共享接口与实现接口说明方法来定义C++的类:<br>
class STestObjedt {<br>
virtual void Proc1(int x)=0;<br>
virtual char *Func1(int x)=0;<br>
};<br>
class TTestObjedt :public STestObject {<br>
void Proc1(int x);<br>
char *Func1(int x);<br>
void Proc2();<br>
int Func2();<br>
void Free();<br>
};<br>
然后实现这些方法。同样地,C++对象需要一个与之对应的制造函<br>
数,这里以DLL为例<br>
STestObject stdcall export *CreateTestObject() {<br>
return (STestObject *) new TTestObject.Create;<br>
}<br>
Delphi代码可以通过调用制造函数CreateTestObject,很容易地<br>
在C++中创建实例,获得指向该实例的指针值,并以这个指针值来调用<br>
对象中的共享方法。当然,在进行完该对象的相关处理后,千万不要忘<br>
了调用Free释放占用的空间。 </p>

<p>浙江省奉化市房地产管理处 邵辉<br>
</p>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -