用Delphi消费C dll

时间:2012-08-03 00:24:54

标签: c delphi dll freepascal lazarus

我有一个带有此签名的Dll函数:

UInt32 Authenticate(uint8 *Key);

我在Delphi上这样做:

function Authenticate(Key:string) : UInt32; external 'mylib.dll' name 'Authenticate';

但总是,函数返回10(错误代码)和应用程序制动:\

有办法做到这一点吗?

更新: 谢谢你们!你是最棒的!

3 个答案:

答案 0 :(得分:7)

您的代码存在一些问题。

1)uint8是Delphi中Byte的等价,而不是String

2)C代码使用编译器的默认调用约定,通常为__cdecl。另一方面,Delphi的默认调用约定是register。它们彼此不兼容。如果不匹配调用约定,则在运行时函数调用期间将无法正确管理堆栈和CPU寄存器。

C代码的字面翻译将改为:

function Authenticate(Key: PByte) : UInt32; cdecl; external 'mylib.dll';

但是,假设函数实际上期望以null结尾的字符串,那么请改为:

// the function is expecting a pointer to 8-bit data,
// so DO NOT use `PChar`, which is 16-bit in Delphi 2009+...
function Authenticate(Key: PAnsiChar) : UInt32; cdecl; external 'mylib.dll';

我会坚持使用第一个声明,因为它与原始C代码匹配。即使函数期望以null结尾的字符串作为输入,您仍然可以通过类型转换使用PByte传递它:

var
  S: AnsiString;
begin
  Authenticate(PByte(PAnsiChar(S)));
end;

或者,如果函数允许空字符串的NULL输入:

var
  S: AnsiString;
begin
  Authenticate(PByte(Pointer(S)));
end;

答案 1 :(得分:2)

我不会对Remy的回答添加任何内容,但我想提供一些工具列表,这些工具可以帮助将C DLL头转换为Pascal(无特殊顺序):

请注意,这些转换器只能转换60-80%的代码,因此需要进行手动操作。

我能给出的最大的节省时间的方法是尝试找到你的DLL存在的Visual Basic标题翻译,并在http://www.marcocantu.com/tools/vb2delphi.htm使用Marco Cantu的VB转换器。这可能会给你几乎100%的自动转换(当然,如果你只转换DLL头文件)。还有一个商业VBTO转换器,但试用演示足以将VB DLL头转换为Pascal。在此处下载:http://www.vbto.net

从C - / C ++转换的其他提示:

稍微偏离主题,但我认为这可能对某人有用......

答案 2 :(得分:0)

首先,将“string”更改为“pchar”。

除此之外可能还有其他问题。