当前位置:  开发笔记 > 编程语言 > 正文

Delphi PChar到C++ const char*

如何解决《DelphiPChar到C++constchar*》经验,为你挑选了1个好方法。

我试图使用本机程序中的C++ DLL.我按照这里解释的虚拟方法场景

让我们说我的C++函数签名就是这种形式

int Setup(const char* szIp, const char* szPort);

相应的delphi签名是

function Setup(ip, port: PChar):Integer: virtual; cdecl; abstract;

从delphi程序的某个地方我可以打电话

pObj.Setup('192.168.1.100', '97777');

控件进入dll,但szIp和szPort形式参数只接收我从delphi程序传递的ip和port的第一个字符.

我知道它与null在delphi中正确终止字符串有关.所以我也试过以下.

var
  pzIp, pzPort: PChar;
  szIp, szPort: string; 

begin
   szIp   := '192.168.1.2';
   szPort := '9777';
   //initilize memory for pchar vars
   GetMem(pzIp, Length(szIp)+1);
   GetMem(pzPort, Length(szPort)+1);
   //null terminate the strings
   pzIp[Length(szIp)+1] := #0;
   pzPort[Length(szPort)+1] := #0;
   //copy strings to pchar
   StrPCopy(pzIp, szIp);
   StrPCopy(pzPort, szPort);
end.

这也是一种工作方式.当我Writeln pzIppzPort我得到奇怪的结果.

忘了说,来自C++ dll的所有成员函数都是__stdcall正确编译和导出的



1> Deltics..:

在Delphi 2010(和Delphi 2009)中,"char"类型实际上是WIDEChar - 即16位宽.因此,当您调用C++函数时,如果期望CHAR为8位宽(所谓的"ANSI",而不是UNICODE),那么它将错误解释输入参数.

例如,如果你传递字符串'ABC'#0(我显式显示空终止符,但这只是Delphi中字符串的隐式部分,不需要特别添加),这会传递一个指向8字节序列的指针,不是 4个字节!

但是因为字符串中的3个字符只有8位代码点值(在Unicode术语中,这意味着C++代码"看到"的字符串如下所示:

  'A'#0'B'#0'C'#0#0#0

这可以解释为什么你的C++代码似乎只是获得字符串的第一个字符 - 它在一个字符的第二个字节中看到#0并假设它是整个字符串的空终止符.

您需要修改C++代码以正确接收指向WideChar字符串的指针,或者修改Delphi中的函数签名,并将这些字符串传递给C++函数之前将其转换为Delphi代码中的ANSIString:

修改功能签名:

  function Setup(ip, port: PANSIChar):Integer: virtual; stdcall; abstract;

以及相应的"Long hand"显示在调用函数之前将字符串转换为ANSIString - 编译器可能会为您处理此问题,但您可能会发现在代码中清除它而不是依赖于"编译器魔术"是有帮助的:

  var
    sIPAddress: ANSIString;
    sPort: ANSIString;
  begin   
    sIPAddress := '192.168.1.100';
    sPort      := '97777';

    pObj.Setup(sIPAddress, sPort);

    // etc... 

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有