4

as we know from Delphi 2007 and below the strings are not Unicode

Char is 1 byte

AnsiChar 1 byte

from Delphi 2009 and above the strings are Unicode

Char is 2 byte

AnsiChar 1 byte

when i convert my Delphi code from Delphi6 to Delphi 10.2( unicode string) i faced problem of some functions take PAnsiChar to fill array of Char, but the pointer passed is PChar, in non Unicode Delphi i will not get any error

but i will get error in new Delphi example

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 will fill bLocalHost

to fix the error i used

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 

now the result in temp_Buffer( Array of AnsiChar) but we need the result in bLocalHost (array of Char)

is there any function like this copy(PAnsiChar,PChar,size) copy content of PAnsiChar to PChar like array without lost data due the Unicode ,so if temp_Buffer ='some data' then bLocalHost must be ='some data' ?

  • 2
    Most of the Windows API calls have Unicode equivalents. Some are direct replacements with just a W added to the end of the name while others are newer API calls with more features with a similar name. Worthwhile to migrate to these instead of continuing to use the ANSI versions. Or in this case use GetAddrInfoW to also get ready for IPv6. – Brian Mar 26 '19 at 13:17
  • 2
    Exactly. Stop using ANSI text, and the problem evaporates. – David Heffernan Mar 26 '19 at 13:23
  • 1
    Or, if you must really use AnsiString, then use AnsiString and UnicodeString, not some buffers allocated otherwise. Use the W suffixed API functions and UnicodeStrings, and simple convert any AnsiString to UnicodeString. You can cast UnicodeString to PWideChar to call such an API. Even your buffer can be the payload of a UnicodeString. – Rudy Velthuis Mar 26 '19 at 13:28
  • 3
    the A version of API calls are internally converted to Unicode anyway, so you'll end up wasting more CPU cycles than necessary – phuclv Mar 26 '19 at 13:32

1 Answers1

2

There is no function to assign the content of an AnsiChar array to a (Wide)Char array without converting the data. Use the Win32 API's MultiByteToWideChar() function, or the RTL's UnicodeFromLocaleChars() function, for that purpose.

Otherwise, you can change your bLocalHost variable to be an AnsiChar array. Or, you can change it to be a (Unicode)String and let the RTL convert the data for you when assigning a null-terminated (P)AnsiChar directly to it.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • thanks,i solved it using this functions `var str:string; str:=StrPas(temp_Buffer); StrPCopy(bRemoteHost,str);` the final result will be as you said – Deaa Darawsheh Mar 27 '19 at 09:34