0

我有一个用 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 方面获得解决方案。

4

3 回答 3

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显式使用。

于 2012-06-29T09:23:31.110 回答
2

我曾尝试在 Delphi 2006 中将我的 tmpString 定义为 WideString,但我相信 WideString 和 XE2 Unicode 字符串有很大不同?

他们是这样。但是,它们都可以从/转换为 C 风格的以 #0 结尾的 WideChar 数组,也就是 PWideChar。唯一的潜在问题是您不能传入包含 #0 的字符串,而不是作为终止符。

如果您尝试调用UnicodeString带有WideString参数的函数接受 a ,您的反对将是有效的,但这不是您正在做的事情。因此,您已经找到的解决方案是正确的。

于 2012-06-29T09:27:20.223 回答
0

这实际上取决于 DLL 如何使用PWideChar传递给它的内容。只要 DLL 不对内存的分配方式做任何假设,它只从内存中读取或写入内存,那么 aWideString就可以正常工作。 Widestring并且UnicodeString由 RTL 以不同方式管理,但它们都包含 UTF-16 编码的有效负载,因此它们彼此内容兼容。两者都#0在其有效负载的末尾包含一个字符,这很重要,因为 DLL 只接受一个PChar指针,因此当转换为PChar. 为避免这种依赖性,您应该更新 DLL 以接受字符串长度作为参数,例如:

D2006:

function DLL_Call(S: PWideChar; L: Integer); stdcall; external 'mylib.dll'; 

var 
  tmpString: WideString; 

tmpString := 'hello'; 
DLL_Call(PWideChar(tmpString), Length(tmpString)); 

XE2:

function DLL_Call(S: PChar; L: Integer); stdcall; external 'mylib.dll'; 

var 
  tmpString: String; 

tmpString := 'hello'; 
DLL_Call(PChar(tmpString), Length(tmpString)); 
于 2012-06-29T09:26:15.980 回答