首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi PChar to C++ const char*

Delphi PChar to C++ const char*
EN

Stack Overflow用户
提问于 2009-09-09 10:16:08
回答 3查看 9.3K关注 0票数 7

我正在尝试使用本地程序中的C++动态链接库。我遵循的是here解释的虚拟方法场景

假设我的C++函数签名的形式是

代码语言:javascript
复制
int Setup(const char* szIp, const char* szPort);

相应的delphi签名是

代码语言:javascript
复制
function Setup(ip, port: PChar):Integer: virtual; cdecl; abstract;

从delphi程序的某个地方我可以调用

代码语言:javascript
复制
pObj.Setup('192.168.1.100', '97777');

控制进入动态链接库,但是szIp和szPort形参只接收我从delphi程序传递的ip和端口的第一个字符。

我知道这与在delphi中正确地使用null来终止字符串有关。所以我也尝试了下面的方法。

代码语言:javascript
复制
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编译的,并正确导出

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-09-09 11:36:46

在Delphi2010(和Delphi2009)中,"char“类型实际上是一个WIDEChar -即16位宽。因此,当你调用你的C++函数时,如果它期望字符是8位宽(所谓的"ANSI",而不是UNICODE),那么它就会错误地解释输入参数。

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

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

代码语言:javascript
复制
  'A'#0'B'#0'C'#0#0#0

这就解释了为什么您的C++代码似乎只获取字符串的第一个字符-它在第一个字符的第二个字节中看到#0,并假设它是整个字符串的空终止符。

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

修改后的函数签名:

代码语言:javascript
复制
  function Setup(ip, port: PANSIChar):Integer: virtual; stdcall; abstract;

以及相应的“长手”,在调用函数之前显示字符串到ANSIString的转换-编译器可能会为您处理这一点,但您可能会发现在代码中清楚地说明这一点而不是依赖于“编译器魔术”是有帮助的:

代码语言:javascript
复制
  var
    sIPAddress: ANSIString;
    sPort: ANSIString;
  begin   
    sIPAddress := '192.168.1.100';
    sPort      := '97777';

    pObj.Setup(sIPAddress, sPort);

    // etc... 
票数 18
EN

Stack Overflow用户

发布于 2009-09-09 11:03:53

两个编译器中的char大小是否相同?如果您使用的是D2009/D2010,则char现在是16位。

票数 4
EN

Stack Overflow用户

发布于 2009-09-09 10:21:58

如果我理解正确的话,你的函数原型也应该是stdcall。

代码语言:javascript
复制
function Setup(ip, port: PChar):Integer: virtual; stdcall; abstract;

ps。Delphi字符串已经以null结尾。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1398763

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档