John Lewis
John Lewis

Reputation: 347

C Unions in Delphi

I would like to translate some type definitions from winnt.h which contain some unions with bitfields. However, is this the correct way of doing it? I am particularly not sure about the union in _TP_CALLBACK_ENVIRON_V3.

  typedef struct _UMS_SYSTEM_THREAD_INFORMATION {
      ULONG UmsVersion;
      union {
          struct {
              ULONG IsUmsSchedulerThread : 1;
              ULONG IsUmsWorkerThread : 1;
          } DUMMYSTRUCTNAME;
          ULONG ThreadUmsFlags;
      } DUMMYUNIONNAME;
  } UMS_SYSTEM_THREAD_INFORMATION, *PUMS_SYSTEM_THREAD_INFORMATION;

  typedef struct _TP_CALLBACK_ENVIRON_V3 {
    TP_VERSION                         Version;
    PTP_POOL                           Pool;
    PTP_CLEANUP_GROUP                  CleanupGroup;
    PTP_CLEANUP_GROUP_CANCEL_CALLBACK  CleanupGroupCancelCallback;
    PVOID                              RaceDll;
    struct _ACTIVATION_CONTEXT        *ActivationContext;
    PTP_SIMPLE_CALLBACK                FinalizationCallback;
    union {
        DWORD                          Flags;
        struct {
            DWORD                      LongFunction :  1;
            DWORD                      Persistent   :  1;
            DWORD                      Private      : 30;
        } s;
    } u;
    TP_CALLBACK_PRIORITY               CallbackPriority;
    DWORD                              Size;
} TP_CALLBACK_ENVIRON_V3;

type
  UMS_SYSTEM_THREAD_INFORMATION = record
    UmsVersion: ULONG;
    ThreadUmsFlags: ULONG;
    case Integer of
      0:(IsUmsSchedulerThread : ULONG);
      1:(IsUmsWorkerThread : ULONG);
  end;
  PUMS_SYSTEM_THREAD_INFORMATION = ^UMS_SYSTEM_THREAD_INFORMATION;

  TP_CALLBACK_ENVIRON_V3 = record
    Version: TP_VERSION;
    Pool: PTP_POOL;
    CleanupGroup: PTP_CLEANUP_GROUP;
    CleanupGroupCancelCallback: PTP_CLEANUP_GROUP_CANCEL_CALLBACK;
    RaceDll: PVOID;
    ActivationContext: PACTIVATION_CONTEXT; // Pointer
    FinalizationCallback: PTP_SIMPLE_CALLBACK;
    case Flags: DWORD of
      1: (LongFunction: DWORD)
      1: (Persistent: DWORD)
      30: (Private: DWORD)
    end;
    CallbackPriority: TP_CALLBACK_PRIORITY;
    Size: DWORD;
  end;
  PTP_CALLBACK_ENVIRON = ^TP_CALLBACK_ENVIRON_V3;

Upvotes: 2

Views: 656

Answers (2)

Rudy Velthuis
Rudy Velthuis

Reputation: 28836

As noted, the ':' notations are bit fields. There is no direct solution, but there is a simple way to translate them that makes them useful again. See my article that describes this. It uses a simple set of functions to get or set a number of bits and to shift them into place, and a clever way (I did not invent it, BTW) to declare them, using the rather unknown property index.

Take a look here: Pitfalls of converting

The idea came from a Stack Overflow answer.

FWIW, the article also describes how to handle unions in such translations.

Upvotes: 1

Those : something notations are bit fields. There is no direct Pascal equivalent.

However, since the three bitfields combined are a complete dword, a general outline for the equivalent becomes something like this:

type
  _TP_CALLBACK_ENVIRON_V3 = record
  ...
    FinalizationCallback: PTP_SIMPLE_CALLBACK;
    case Integer of
    1: (Flags: DWord);
    2: (LongFunctionPersistentPrivate: DWord)
  end;

Upvotes: 4

Related Questions