我有一个用XE2编写的DLL,它以PChar作为参数(因此是一个unicode字符串)。我希望在Delphi 2006中编写一个调用此DLL的应用程序。这是可能的,我如何传递PChar参数?如果我在Delphi XE2中这样做,我只会这样做:
tmpString := 'hello';
DLL_Call(PChar(tmpString));
我在Delphi 2006中尝试将我的tmpString定义为WideString,但我相信WideString和XE2 Unicode字符串差异很大?
有没有办法可以将字符串正确传递给DLL?我控制DLL源代码,所以我显然可以将函数定义更改为PAnsiChar,但我不想这样做,我希望尽可能从Delphi 2006方面获得解决方案。
答案 0 :(得分:3)
您需要将该函数声明为接收PWideChar
。然后使用WideString
来保存有效负载。
function DLL_Call(S: PWideChar); stdcall; external 'mylib.dll';
......
var
tmpString: WideString;
......
tmpString := 'hello';
DLL_Call(PWideChar(tmpString));
请记住,PChar
是别名。在Unicode前Delphi中,它是PAnsiChar
的别名。在Unicode Delphi中,它是PWideChar
的别名。 Pre-Unicode Delphi完全能够调用任何Unicode API,但必须明确使用PWideChar
。
答案 1 :(得分:2)
我在Delphi 2006中尝试将我的tmpString定义为WideString,但我相信WideString和XE2 Unicode字符串差异很大?
他们这样做。但是,它们都可以从/转换为C风格的#0端接的WideChar数组,换句话说就是PWideChar。唯一可能的问题是你不能传入包含#0的字符串而不是作为终结符。
如果您尝试调用接受带有UnicodeString
参数的WideString
的函数,您的异议将是有效的,但这不是您正在做的事情。所以你已经找到的解决方案是正确的。
答案 2 :(得分:0)
这实际上取决于DLL如何使用传递给它的PWideChar
。只要DLL没有对内存的分配方式做出任何假设,它只会从内存中读取或写入内存,那么WideString
就可以了。 RTL对Widestring
和UnicodeString
进行了不同的管理,但它们都包含UTF-16编码的有效负载,因此它们彼此内容兼容。两者在其有效负载的末尾都包含#0
字符,这很重要,因为DLL只接受PChar
指针,因此当转换为{时,两个字符串类型都被DLL视为由null终止{1}}。为了避免这种依赖性,您应该更新DLL以接受字符串长度作为参数,例如:
D2006:
PChar
XE2:
function DLL_Call(S: PWideChar; L: Integer); stdcall; external 'mylib.dll';
var
tmpString: WideString;
tmpString := 'hello';
DLL_Call(PWideChar(tmpString), Length(tmpString));