[fpc-pascal]Local Ip Address
Michalis Kamburelis
michalis at camelot.homedns.org
Mon Feb 23 18:40:08 CET 2004
Crabtree, Chad wrote:
> Ok. Thank you that worked however I'd like to ask some questions. I tried
> to find the answer by looking at the source code however I'm confused by
> this code
>
> abcd:=PABCD(phe^.h_addr_list[0])^;
>
> I beleive this automaticly parses h_addr_list[0] into the record. Not sure
> why but that's ok. However when I looked at the winsock source most specifly
> hostent record type I was not able to winnow any meaning out of.
>
> case byte of
> 0: (h_addr_list: ^pchar);
> 1: (h_addr: ^pchar)
>
> Which is the last part of the record. Now please correct me if I'm wrong.
> but the h_addr_list is an array of bytes, however the type that's declared
> is a pointer to pchar right? It's just muddy for me. This is my first real
> forray into compiled languages, I can do what I want to with python or perl
> but this is a little beyond me.
>
> Thanks
> Chad
I perfectly understand your confusion -- hostent record type isn't a
good example of "nice and clean type design". It was designed in C so
it's rather "follow-the-pointers type design".
First of all, forget about "PChar". As you said, h_addr_list[0]^ is not
a null-terminated array of chars. It's just array of bytes. You have to
look at h_length to now how long (in bytes) it is.
h_addr_list is a "null-terminated list of pointers to addresses". This
means that if you want to enumerate all addresses from hostent you have
to do something like that
i:=0;
whle phe^.h_addr_list[i] <> nil do
begin
... here is the code to do something with an i-th address.
phe^.h_addr_list[i] is a *pointer* to this address.
phe^.h_length tells you how long is this address, in bytes.
Inc(i);
end;
That's why I wrote in code attached to last mail that h_length should be
4 for normal Internet address (as long as you forget about IPv6). This
means that phe^.h_addr_list[0] is a pointer to four-byte array that
contains the address you want to get.
So now we want to extract those four bytes. There are many ways to do
this in Pascal. I wrote
abcd:=PABCD(phe^.h_addr_list[0])^;
This line was not doing any "automatic string parsing" -- it was rather
telling the compiler "treat phe^.h_addr_list[0] as a pointer to a record
TABCD". And record TABCD is just a four-byte array.
One may also write something like that, maybe this will be more clear:
type
TFourByteArray = array[0..3]of byte;
PFourByteArray = ^TFourByteArray;
....
Writeln(Format('%d.%d.%d.%d', [
PFourByteArray(phe^.h_addr_list[0])^[0],
PFourByteArray(phe^.h_addr_list[0])^[1],
PFourByteArray(phe^.h_addr_list[0])^[2],
PFourByteArray(phe^.h_addr_list[0])^[3]
]));
Hope this helps,
Michalis
More information about the fpc-pascal
mailing list