我有一个用XE2编写的DLL,它接受一个PChar作为参数(因此是一个unicode字符串)。我希望用Delphi2006编写一个调用这个DLL的应用程序。有没有可能,我该如何传入PChar参数?如果我用的是Delphi XE2,我会简单地这样做:
tmpString := 'hello';
DLL_Call(PChar(tmpString));我曾尝试在Delphi2006中将我的tmpString定义为WideString,但我认为WideString和XE2 Unicode字符串有很大的不同?
有没有一种方法可以将字符串正确地传递给DLL?我控制着DLL源代码,所以我显然可以将函数定义更改为PAnsiChar,但我不希望这样做,如果可能的话,我希望从Delphi2006方得到一个解决方案。
发布于 2012-06-29 17:23:31
您需要将该函数声明为接收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的别名。Unicode之前的Delphi完全能够调用任何Unicode,但必须显式使用PWideChar。
发布于 2012-06-29 17:27:20
我试过在Delphi2006中将我的tmpString定义为WideString,但我认为WideString和XE2 Unicode字符串有很大的不同?
确实如此。但是,它们都可以从C风格的#0终止的WideChar数组(换句话说,PWideChar )转换为C风格的#0终止数组。唯一的潜在问题是,除了作为终止符,您不能传入包含#0的字符串。
如果您试图调用一个接受带有WideString参数的UnicodeString的函数,那么您的反对意见将是有效的,但这不是您要做的。所以你已经找到的解决方案是正确的。
发布于 2012-06-29 17:26:16
这实际上取决于DLL如何使用传递给它的PWideChar。只要DLL不对内存的分配方式做任何假设,它只从内存中读取或写入内存,那么WideString就会工作得很好。Widestring和UnicodeString的管理方式不同,但它们都包含UTF16编码的有效载荷,因此它们彼此是内容兼容的。这两种类型的有效负载的末尾都包含一个#0字符,这一点很重要,因为DLL只接受PChar指针,所以当转换为PChar时,这两种字符串类型都被DLL视为以null结尾。为了避免这种依赖性,您应该更新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)); https://stackoverflow.com/questions/11259106
复制相似问题