gpt4 book ai didi

c++ - Delphi PChar 到 C++ const char*

转载 作者:可可西里 更新时间:2023-11-01 18:04:47 26 4
gpt4 key购买 nike

我正在尝试使用 native 程序中的 C++ dll。我正在按照解释的虚拟方法场景 here

假设我的 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的第一个字符。

我知道它与在 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 编译并正确导出的

最佳答案

在 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++ 代码似乎只获取字符串的第一个字符 - 它在第一个字符的 2nd 字节 中看到 #0并假设它是整个字符串的空终止符。

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

修改后的函数签名:

  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...

关于c++ - Delphi PChar 到 C++ const char*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1398763/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com