How to convert from PAnsichar to PWidechar?

Xenon Xe picture Xenon Xe · Sep 12, 2013 · Viewed 11.4k times · Source

I am implementing Ping function using windows API in delphi-xe3 from here (http://delphi.about.com/od/internetintranet/l/aa081503a.htm).

I am having problem with the following function.It displays error incompatible type Pansichar and Pwidechar.I replaced Pchar with PAnsichar now it displays exception 'Error getting IP from HostName'.

I am testing it with localhost.

Please guide whats the proper conversion.

const ADP_IP = '127.0.0.1';

procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var
  phe: PHostEnt;
  pac: PChar;
  GInitData: TWSAData;
begin
  WSAStartup($101, GInitData);
  try
    phe := GetHostByName(PChar(AIP));
    if Assigned(phe) then
    begin
      pac := phe^.h_addr_list^;
      if Assigned(pac) then
      begin
        with TIPAddr(AInAddr).S_un_b do begin
          s_b1 := Byte(pac[0]);
          s_b2 := Byte(pac[1]);
          s_b3 := Byte(pac[2]);
          s_b4 := Byte(pac[3]);
        end;
      end
      else
      begin
        raise Exception.Create('Error getting IP from HostName');
      end;
    end
    else
    begin
      raise Exception.Create('Error getting HostName');
    end;
  except
    FillChar(AInAddr, SizeOf(AInAddr), #0);
  end;
  WSACleanup;
end;

Answer

David Heffernan picture David Heffernan · Sep 12, 2013

You don't want to convert from PAnsiChar to PWideChar. On your Unicode Delphi your PChar maps to PWideChar. But gethostbyname receives PAnsiChar. You need to convert from Unicode to ANSI.

Code it like this:

phe := gethostbyname(PAnsiChar(AnsiString(AIP)));

In other words, convert your string to AnsiString, and then cast as PAnsiChar. Personally I'd declare the AIP parameter to be AnsiString.

procedure TranslateStringToTInAddr(const AIP: AnsiString; var AInAddr);

And then write the call to gethostbyname like so:

phe := gethostbyname(PAnsiChar(AIP));

That untyped var parameter looks dubious to me. I see no compelling reason for its use. What's wrong with declaring it to be of type TIPAddr? Your FillChar is somewhat dubious. How can you use SizeOf on an untyped parameter?