How to convert C union inside a struct to Delphi
I need help to convert this C type declaration to Delphi:
typedef struct _IO_STATUS_BL开发者_Go百科OCK {
union {
NTSTATUS Status;
PVOID Pointer_;
} ;
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
From Hardlinks.pas
in the JCL:
type
IO_STATUS_BLOCK = record
case integer of
0:
(Status: NTSTATUS);
1:
(Pointer: Pointer;
Information: ULONG); // 'Information' does not belong to the union!
end;
// PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
In addition to the other posts, you might want to read Pitfalls of Conversion. Rudy's articles are a goldmine of information regarding Delphi / C / C++ interoperability.
A C Union can be translated with a case selector inside a record, problem here is that Delphi doesn't allow anything after the Case statement. This can be solved with a nested Case statement, like this:
_IO_STATUS_BLOCK = record
case Integer of
0: (
case Integer of
0: (
Status: NTSTATUS);
1: (
Pointer_: Pointer);
2: (Information: ULONG_PTR));
end;
IO_STATUS_BLOCK = _IO_STATUS_BLOCK;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
/EDIT: To make the Offsets correct (see comments below) padding is needed, the corrected version is below. It doesn't offer much advantage here but it would if more field or even unions follow behind the first union:
_IO_STATUS_BLOCK = record
case Integer of
0: (
case Integer of
0: (Status: NTSTATUS);
1: (Pointer_: Pointer));
1: (
Pad: DWORD;
Information: ULONG_PTR);
end;
IO_STATUS_BLOCK = _IO_STATUS_BLOCK;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
/EDIT2: A better version looks like this:
_IO_STATUS_BLOCK = record
case Integer of
0: (
Status: NTSTATUS;
Pointer_: Pointer);
1: (
case Padding: DWORD of
0: (
Information: ULONG_PTR));
end;
IO_STATUS_BLOCK = _IO_STATUS_BLOCK;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
精彩评论