问题
Background:
Translating the IP_OPTION_INFORMATION32 and ICMP_ECHO_REPLY32 structures for 64-bit compiler I got stucked with data types to use there. Structure definitions from the reference:
The IP_OPTION_INFORMATION32 structure:
typedef struct _IP_OPTION_INFORMATION32 {
UCHAR Ttl;
UCHAR Tos;
UCHAR Flags;
UCHAR OptionsSize;
UCHAR * POINTER_32 OptionsData;
} IP_OPTION_INFORMATION32, *PIP_OPTION_INFORMATION32;
I would translate this way (for Delphi XE2, 64-bit target platform). As you can see, I don't know what type to use for the OptionsData
field of the structure:
IP_OPTION_INFORMATION32 = record
Ttl: UCHAR;
Tos: UCHAR;
Flags: UCHAR;
OptionsSize: UCHAR;
OptionsData: // what should I use here for UCHAR * POINTER_32 ?
end;
ICMP_ECHO_REPLY32 structure:
typedef struct icmp_echo_reply32 {
IPAddr Address;
ULONG Status;
ULONG RoundTripTime;
USHORT DataSize;
USHORT Reserved;
VOID * POINTER_32 Data;
struct ip_option_information32 Options;
} ICMP_ECHO_REPLY32, *PICMP_ECHO_REPLY32;
For Delphi XE2 64-bit target platform I would write:
ICMP_ECHO_REPLY32 = record
Address: TIPAddr; // defined before
Status: ULONG;
RoundTripTime: ULONG;
DataSize: USHORT;
Reserved: USHORT;
Data: // what should I use here for VOID * POINTER_32 ?
Options: IP_OPTION_INFORMATION32;
end;
Question:
How would you define the UCHAR * POINTER_32
and VOID * POINTER_32
types in Delphi for 64-bit platform target ? As far as I know, there is no 32-bit pointer type available for 64-bit platform target and I just don't like it to be defined e.g. as a Int32
type :-)
What is the most precise translation for the mentioned types ?
回答1:
The issue of what POINTER_32
is covered in another Stack Overflow question: POINTER_32 - what is it, and why?
You would use it when performing interop with structs that are defined in a different process, one that has 32 bit pointers.
You don't have the equivalent of __ptr32
in Delphi so you have simply no choice other than to declare it as a 32 bit integer. I would use an unsigned type.
回答2:
In this case UInt32
(or Cardinal, DWORD etc - anything unsigned 32 bit) would be fine. All you need to do is to declare unsigned 32 bit at proper position of structure (record). CPU would not care, compiler would not care (you can typecast to pointer if needed) is it actually a pointer or not. Even signed 32 bit would work unless you would do some math with value and processor's flags checking.
And another thing in structure translations from C to Delphi: be sure that original alignment was 4 bytes (32 bit per item), because record
unlike packed record
(no alignment) by default using same 4 bytes alignment. Else you can have issues by applying your records to data like
type
Picmp_echo_reply32 = ^icmp_echo_reply32;
...
data_size := Picmp_echo_reply32(@mybuf[some_offset]).DataSize;
or
var
icmp_echo: Picmp_echo_reply32;
...
icmp_echo := @buf[offset];
reserved := icmp_echo.Reserved;
来源:https://stackoverflow.com/questions/17084031/how-to-define-uchar-pointer-32-and-void-pointer-32-types-in-delphi