I use Delphi XE. There is such a code

function ResolveAddress(Address: String): TInAddr; var Host: PHostEnt; begin Result.S_addr := inet_addr(PChar(Address)); if Result.S_addr = INADDR_NONE then begin Host := gethostbyname(PChar(Address)); if Host <> nil then Result := PInAddr(Host.h_addr_list^)^; end; end; 

If I call ResolveAddress('localhost') , then inet_addr in the function above returns -1, and if I write

 function ResolveAddress(Address: String): TInAddr; var Host: PHostEnt; begin Result.S_addr := inet_addr('localhost'); if Result.S_addr = INADDR_NONE then begin Host := gethostbyname(PChar(Address)); if Host <> nil then Result := PInAddr(Host.h_addr_list^)^; end; end; 

That's all fine.

I did this inet_addr(PAnsiChar(AnsiString(Address))) , but the result is the same.

  • The same conversion (to PAnsiChar ) is worth GetHostByName for GetHostByName , as far as I can see ... - kami
  • before GetHostByName does not reach inet_addr(PChar(Address)) returns earlier - 1 - gregor

2 answers 2

The function must be declared like this:

 function ResolveAddress(const Address: AnsiString): TInAddr; 

and replace all PChar with PAnsiChar :

 Result.S_addr := inet_addr(PAnsiChar(Address)); ... Host := gethostbyname(PAnsiChar(Address)); 

Further, the inet_addr function accepts only IP addresses in the xxxx format and it cannot work with a string like localhost by design. The function gethostbyname used for this.

Therefore, if you pass the string localhost to the input of your ResolveAddress , then inet_addr quite naturally will not work and the code will go into the branch with getting the address by name, via gethostbyname . This is the normal behavior of your function.

    From the working draft:

     function ValidateIP(const IP: AnsiString): TInAddr; begin Result := TInAddr(inet_addr(PAnsiChar(@IP[1]))); if DWORD(Result) = INADDR_NONE then raise EArgumentException.CreateFmt('IP adress ''%s'' is not valid!', [string(IP)]); end; 

    You can also check the input parameter for Length> 0.