用Delphi消费C dll
我有一个带有此签名的Dll函数:
UInt32 Authenticate(uint8 *Key);
我在Delphi上这样做:
function Authenticate(Key:string) : UInt32; external 'mylib.dll' name 'Authenticate';
但总是,函数返回10(错误代码)和应用程序刹车:
有办法做到这一点吗?
更新: 谢谢你们! 你是最好的!
您的代码存在一些问题。
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;
我不会对Remy的回答添加任何内容,但是我想提供一些工具列表,这些工具可以帮助将C DLL头转换为Pascal(无特殊顺序):
- http://sourceforge.net/projects/c2pas
- http://www.astonshell.com/freeware/c2pas32
- http://cc.embarcadero.com/item/26951
- http://rvelthuis.de/programs/convertpack.html
- http://www.drbob42.com/delphi/headconv.htm
- http://wiki.lazarus.freepascal.org/H2Pas
- http://wiki.freepascal.org/Chelper
请注意,这些转换器只能转换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 ++转换的其他提示:
- http://rvelthuis.de/articles/articles-convert.html
- http://rvelthuis.de/articles/articles-pchars.html
- http://rvelthuis.de/articles/articles-cobjs.html
- http://rvelthuis.de/articles/articles-cppobjs.html
- http://www.awitness.org/delphi_pascal_tutorial/c++_delphi
稍微偏离主题,但我认为这可能对某人有用……
对于初学者,将“string”更改为“pchar”。
除此之外可能还有其他问题。