将 ansichar 数组复制到 char delphi 10.2 数组

Posted

技术标签:

【中文标题】将 ansichar 数组复制到 char delphi 10.2 数组【英文标题】:copy array of ansichar to array of char delphi 10.2 【发布时间】:2019-08-16 21:12:07 【问题描述】:

从 Delphi 2007 及以下我们知道,字符串不是 Unicode

字符为 1 个字节

AnsiChar 1 字节

Delphi 2009 及以上版本的字符串是 Unicode

Char 是 2 个字节

AnsiChar 1 字节

当我将 Delphi 代码从 Delphi6 转换为 Delphi 10.2(unicode 字符串)时 我遇到了一些函数用 PAnsiChar 填充 Char 数组的问题,但是传递的指针是 PChar,在非 Unicode Delphi 中我不会得到任何错误

但我会在新的 Delphi 中遇到错误 例子

procedure TswSocket.SetLocalHost(AHost : AnsiString);
var
  HostIpAddress : TIPAddress;
  Buffer: PChar;

  begin
  Buffer:=StrAlloc(Length(AHost)+1);
  strpcopy(Buffer,AHost);
  Buffer[Length(AHost)]:=#0;
  bLocalHost:=StrAlloc(MAXGETHOSTSTRUCT);
  hGetLocalHost:=WSAAsyncGetHostByName(Self.hWindow,WM_SOCKETGETHOSTBYNAME,Buffer,bLocalHost,MAXGETHOSTSTRUCT); // Buffer,bLocalHost must be PAnsiChar instead of PChar

WSAAsyncGetHostByName 将填充 bLocalHost

修复我使用的错误

procedure TswSocket.SetLocalHost(AHost : AnsiString);
var
  HostIpAddress : TIPAddress;
  Buffer,temp_Buffer : PAnsiChar;

  begin
  Buffer:=AnsiStrAlloc(Length(AHost)+1);
  strpcopy(Buffer,AHost);
  Buffer[Length(AHost)]:=#0;

  temp_Buffer:=AnsiStrAlloc(MAXGETHOSTSTRUCT);
  bLocalHost:=StrAlloc(MAXGETHOSTSTRUCT);
  hGetLocalHost:=WSAAsyncGetHostByName(Self.hWindow,WM_SOCKETGETHOSTBYNAME,Buffer,temp_Buffer,MAXGETHOSTSTRUCT); // no error : Buffer,temp_Buffer is PAnsiChar 

现在是 temp_Buffer(AnsiChar 数组)中的结果,但我们需要 bLocalHost(Char 数组)中的结果

有没有类似这个副本的函数(PAnsiChar,PChar,size) 将 PAnsiChar 的内容复制到类似数组的 PChar 中,不会由于 Unicode 而丢失数据,所以如果 temp_Buffer ='some data' 那么 bLocalHost 必须是 ='some data' ?

【问题讨论】:

大多数 Windows API 调用都有 Unicode 等效项。有些是直接替换,只是在名称末尾添加了一个 W,而另一些是更新的 API 调用,具有更多具有相似名称的功能。值得迁移到这些而不是继续使用 ANSI 版本。或者在这种情况下,使用 GetAddrInfoW 也为 IPv6 做好准备。 没错。停止使用 ANSI 文本,问题就消失了。 或者,如果你真的必须使用 AnsiString,那么使用 AnsiString 和 UnicodeString,而不是其他分配的一些缓冲区。使用 W 后缀的 API 函数和 UnicodeStrings,简单地将任何 AnsiString 转换为 UnicodeString。您可以将 UnicodeString 转换为 PWideChar 以调用此类 API。甚至您的缓冲区也可以是 UnicodeString 的有效负载。 A 版本的 API 调用无论如何都会在内部转换为 Unicode,因此您最终会浪费不必要的 CPU 周期 【参考方案1】:

没有函数可以在不转换数据的情况下将AnsiChar 数组的内容分配给(Wide)Char 数组。为此,请使用 Win32 API 的 MultiByteToWideChar() 函数或 RTL 的 UnicodeFromLocaleChars() 函数。

否则,您可以将 bLocalHost 变量更改为 AnsiChar 数组。或者,您可以将其更改为 (Unicode)String,并让 RTL 在直接为其分配以空字符结尾的 (P)AnsiChar 时为您转换数据。

【讨论】:

谢谢,我用这个函数解决了它var str:string; str:=StrPas(temp_Buffer); StrPCopy(bRemoteHost,str);最终结果会如你所说

以上是关于将 ansichar 数组复制到 char delphi 10.2 数组的主要内容,如果未能解决你的问题,请参考以下文章

delphi 'Char' and 'AnsiChar'报错问题

delphi 'Char' and 'AnsiChar'报错问题

Delphi中等效的BYTE数组(BYTE [])与null终止一个整数?

C: unsigned char * bytes 数组将元素复制到其他 unsigned char * 数组

C++ 将 std::string 复制到没有空终止的 char 数组

如何将std :: string复制到unsigned char数组?