请问个位高手,如何实现不同语言之间的调用呢?(200分)

  • 主题发起人 主题发起人 budong
  • 开始时间 开始时间
B

budong

Unregistered / Unconfirmed
GUEST, unregistred user!
请问:
1,如何在Delphi中调用C呢?
2。如何实现他们之间的参数传输呢?
3。数据的传输要安全时,如何处理呢?
谢谢!
 
D e l p h i 提供了直接在D e l p h i 程序中链接由其他编译器生成的O B J 文件的功能。可以通过$LINK 或
$ L 将一个目标文件链接入你的P a s c a l 程序中。如下:
在目标文件被链接后,必须对将在P a s c a l 代码中使用的函数进行定义。使用e x t e r n a l 指示字可以指
示编译器应该等到链接时再找函数名。例如,下面代码中声明的外部函数F o o ,它既没有参数也没有返
回值。
尽管它表面看起来功能很强大,但它还是有许多的限制:
•
Object Pascal 能直接访问O B J 文件中的代码,但不能访问它的数据(后面,你将会可看到访问其数
据的技巧),然而P a s c a l 的数据可以被O B J 文件访问。
•
Object Pascal 不能与L I B 文件(静态链接库)链接。
•
包含了C + +类的O B J 文件不能被链接,因为其中隐含了对C + +类的RT L 的引用,虽然这也可以解
决,比如把C + +的RT L 加入O B J 文件中,但是这样做是非常麻烦的。
•
O B J 文件必须为Intel OMF 格式,这是B o r l a n d 编译器生成的一种格式。Microsoft C++编译器生成
的C O F F 格式的O B J 文件不可用。
注意Delphi 编译器考虑到了以前版本的一些令人讨厌的限制,并解决了OBJ 文件对OBJ 文件的
引用问题。在早期版本的Delphi 中一个OBJ 文件不能对另一个OBJ 文件的代码和数据进行引用。
调用一个函数
假设有一个C + +类型的包含下列原型函数的目标文件c c o d e . o b j 。
在D e l p h i 程序中要调用这个函数,必须首先利用$ L 或$ L I N K 把目标文件链接进E X E 文件:
{$L ccode.obj}
做完这项工作后,必须为此函数创建一个Object Pascal 的声明:
function SayHello(Text: PChar): integer;
external;
注意在C++中使用_ _fastcall 指示字是为了保证与Object Pascal 的调用约定方式兼容。如果C++
的原型与Object Pascal 采用了不一致的调用约定方式,那么调用就会失败。这是大多数程序员
容易出现的错误。
命名问题
C + +编译器可能会缺省地将没用e x t e r n “C ”修饰符显式声明的名称改掉。然而,Object Pascal 编
译器不会这么做。例如,当利用T D U M P 去查看先前在c c o d e . o b j 中声明的S AY H E L L O 函数的引出符号
名时,其名称为@ S AY H E L L O $ q q r p c 。而在Object Pascal 中引入的函数名为S AY H E L L O ( P a s a c l 强制符
号为大写)。
表面上,似乎有一个问题:如果函数的名称不总是一致,D e l p h i 编译器如何去找到它呢?答案是:
D e l p h i 编译器简单地忽略掉@符号以及位于$符号后面的所有字符就行了。不过,这样会产生负面的影
响。
C + +之所以要把函数的名称改成这样,是为了以后可以重载函数(指函数的名称相同,但参数列表
不同)。如果同一个函数被重载多次,而D e l p h i 编译器又忽略了@符号以及$符号后面的所有字符,那
么到底调用哪个函数就分不清了。由于这个原因,本书建议你不要调用O B J 文件中的重载函数。
注意除非已使用e x t e r n “c ”来声明的函数或C + +编译器使用了适当的命令行开关。否则,函
数将会被编译器改名。
共享数据
如前所述,从O B J 文件中访问D e l p h i 的数据是可行的。首先是在代码中声明一个全局变量(注意下
划线):
虽然,变量已被初始化,但还不完全合乎要求。
接下来,在C + +模块中,用e x t e r n a l 指示字来声明一个同名的变量:
警告默认情况,Borland C++编译器在e x t e r n a l 变量前加上下划线(例如,G L O B A LVA R 变成
_GLOBALVAR)。你可以用两种方法来避免它:
•
使用命令行开关禁止下划线功能(在Borland C++编译器中是-u-)。
•
在Object Pascal 中,在变量名前加一条下划线。
尽管在Object Pascal 代码中直接共享O B J 文件中的数据是不可能的。但可以变化一下,首先在C + +
的代码中用_ _ e x p o r t 指示字声明要引出的数据,例如,可以将一个字符数组做如下引出:
char __export C_VAR[128;]
接下来,在Object Pascal 中将其声明为一个过程。一定要加上下划线:
procedure _C_VAR;external;//trick to import OBJ data
这将让链接器解决P a s c a l 代码中的_ C _ VA R 引用。最后,可以在Object Pascal 代码中,把_ C _ VA R
作为一个指向数据的指针使用。
例如,下面代码用来得到数组的值:
type
PCharArray = ^ TCharArray;
TCharArray = array[0..127] of char;
function GetCArray : string;
var
A: PCharArray;
begin
A := pCharArray(@_C_VAR);
Result := A^;
end;

下列代码用于设置数组的值:
procedure SetCArray(Const S: string);
var
A: PCharArray;
begin
A := PCharArray(@_C_VAR);
StrLCopy(A^, PChar(S), SizeOf(TCharArray));
end;
 
接受答案了.
 

Similar threads

回复
0
查看
988
不得闲
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部