用Delphi消费C dll

Joã*_*llo 4 c delphi dll freepascal lazarus

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

UInt32 Authenticate(uint8 *Key);
Run Code Online (Sandbox Code Playgroud)

我在Delphi上这样做:

function Authenticate(Key:string) : UInt32; external 'mylib.dll' name 'Authenticate';
Run Code Online (Sandbox Code Playgroud)

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

有办法做到这一点吗?

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

Rem*_*eau 7

您的代码存在一些问题.

1)uint8ByteDelphi中的等价物,而不是String.

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

C代码的字面翻译将是这样的:

function Authenticate(Key: PByte) : UInt32; cdecl; external 'mylib.dll';
Run Code Online (Sandbox Code Playgroud)

但是,假设函数实际上期望以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';
Run Code Online (Sandbox Code Playgroud)

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

var
  S: AnsiString;
begin
  Authenticate(PByte(PAnsiChar(S)));
end;
Run Code Online (Sandbox Code Playgroud)

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

var
  S: AnsiString;
begin
  Authenticate(PByte(Pointer(S)));
end;
Run Code Online (Sandbox Code Playgroud)

  • 即使在2009年之前的Delphi版本中,"PAnsiChar"仍优于"PChar".它使代码更加明确,它期望8位字符数据,并且你不必记得将它从`PChar`改为`PAnsiChar`(为了保持与C代码的兼容性),如果项目是稍后升级到2009+版本的Delphi. (5认同)