开发者

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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜