我有一个具有以下签名的Dll函数:
UInt32 Authenticate(uint8 *Key);
我正在使用Delphi进行此操作:
function Authenticate(Key:string) : UInt32; external 'mylib.dll' name 'Authenticate';
但是总是返回函数错误代码10,导致应用程序崩溃:\
有没有正确的处理方法?
更新: 谢谢大家!你们最棒了!
我有一个具有以下签名的Dll函数:
UInt32 Authenticate(uint8 *Key);
function Authenticate(Key:string) : UInt32; external 'mylib.dll' name 'Authenticate';
但是总是返回函数错误代码10,导致应用程序崩溃:\
有没有正确的处理方法?
更新: 谢谢大家!你们最棒了!
uint8
相当于Byte
,而不是String
。__cdecl
。而Delphi的默认调用约定则是register
。它们彼此不兼容。如果调用约定不匹配,在运行时函数调用期间,堆栈和CPU寄存器将无法正确管理。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代码匹配。即使函数需要以空字符结尾的字符串作为输入,你仍然可以通过类型转换使用PByte
传递它:
var
S: AnsiString;
begin
Authenticate(PByte(PAnsiChar(S)));
end;
或者,如果该函数允许将空字符串作为NULL输入:
var
S: AnsiString;
begin
Authenticate(PByte(Pointer(S)));
end;
PAnsiChar
仍然比 PChar
更受欢迎。它使代码更加明确,表明它期望 8 位字符数据,并且如果项目以后升级到 Delphi 2009+ 版本,你不必记得将其从 PChar
更改为 PAnsiChar
(为了与 C 代码保持兼容性)。 - Remy Lebeau虽然略微偏题,但我认为这对某些人可能会有用...
首先,将“string”更改为“pchar”。
除此之外可能还有其他问题。
PAnsiChar
。 - Remy LebeauPByteArray
更精确地表示变量类型。 - JayPChar
也是错误的,因为PChar
并不能替代“指向8字节无符号整数”的指针(当然,string
也不行)。最多应该作为对原问题的评论;它绝对不是一个答案。 - Ken White