2015-01-01 3 views
2

Я хотел бы перевести некоторые определения типов из winnt.h, которые содержат некоторые объединения с битовыми полями. Однако, это правильный способ сделать это? Я особенно не уверен в союзе в _TP_CALLBACK_ENVIRON_V3.C Unions in Delphi

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; 

ответ

4

Те : something нотации битовые поля. Нет прямого эквивалента Паскаля.

Однако, так как три битовые в сочетании являются полный DWORD, общая схема для эквивалента становится чем-то вроде этого:

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

И в современных версиях Delphi записи могут иметь методы и свойства, поэтому вы можете легко имитировать отдельные битовые поля с некоторым соответствующим смещением бит. –

+0

@RemyLebeau Это правильный перевод? http://pastebin.com/ecw5ZLYE –

+0

Джон, вам не нужно заботиться о буквальном переводе битовых полей структуры 'TP_CALLBACK_ENVIRON', поскольку структура среды обратного вызова используется только внутри API-интерфейса пула потоков. Вы не должны получать доступ к каким-либо из этих полей. Таким образом, объединение этих битовых полей в один «DWORD» прекрасен. Ваш предложенный перевод неверен. '1: (LongFunction: DWORD)' обозначает первый бит 'DWORD',' 1: (Persistent: DWORD) 'второй бит' DWORD' и '30: (Private: DWORD)' остается 30 бит ' DWORD'. Вы объявили 3 'DWORD' для тех полей, которые не соответствуют действительности. Сделайте то, что предлагается здесь. – TLama

1

Как уже отмечалось, «:» нотации битовые поля. Прямого решения нет, но есть простой способ перевести их, что делает их полезными снова. См. Мою статью, которая описывает это. Он использует простой набор функций, чтобы получить или установить несколько бит и сдвинуть их на место, и умный способ (я его не изобрел, BTW) объявить их, используя довольно неизвестный индекс свойств.

Посмотрите здесь: Pitfalls of converting

Идея пришла из Stack Overflow answer.

FWIW, статья также описывает how to handle unions в таких переводах.

+0

FWIW, статья на форуме отсутствует. Работайте с моим провайдером, чтобы снова получить его в Интернете. –