2012-11-10 8 views
10
typedef struct _FILE_OBJECTID_INFORMATION { 
    LONGLONG FileReference; 
    UCHAR ObjectId[16]; 
    union { 
     struct { 
      UCHAR BirthVolumeId[16]; 
      UCHAR BirthObjectId[16]; 
      UCHAR DomainId[16]; 
     } DUMMYSTRUCTNAME; 
     UCHAR ExtendedInfo[48]; 
    } DUMMYUNIONNAME; 
} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION; 

Come tradurre un tale sindacato in Delphi?Come si traduce un sindacato C in Delphi?

risposta

19

L'equivalente Pascal di un C union è noto come variant record.

Un tipo di record può avere una parte variante, che si presenta come un caso dichiarazione. La parte della variante deve seguire gli altri campi nella dichiarazione del record.

Per dichiarare un tipo di record con una parte variante, utilizzare la seguente sintassi:

type recordTypeName = record 
    fieldList1: type1; 
    ... 
    fieldListn: typen; 
case tag: ordinalType of 
    constantList1: (variant1); 
    ... 
    constantListn: (variantn); 
end; 

La prima parte della dichiarazione - alla parola riservata caso - è la stessa di quella di un tipo di record standard. Il resto della dichiarazione - dal del caso al punto e virgola finale opzionale - è chiamato la parte variante. Nella parte variante,

  • tag è opzionale e può essere qualsiasi identificatore valido. Se ometti il ​​tag , ometti i due punti (:) anche dopo.
  • ordinalType denota un tipo ordinale.
  • Ogni lista costante è una costante che indica un valore di tipo ordinalType o un elenco delimitato da virgole di tali costanti. Nessun valore può essere rappresentato più di una volta nelle liste costanti .
  • Ogni variante è una lista virgola-delimitato dichiarazioni assomiglia alla fieldList: tipo costruzioni nella parte principale del tipo record. Cioè, una variante ha la forma:

    fieldList1: type1; ... fieldListn: typen;

dove ogni fieldList è un identificatore valido o un elenco separato da virgole identificatori, ogni tipo denota un tipo, e la virgola finale è opzionale. I tipi non devono essere stringhe lunghe, array dinamici, varianti (ovvero tipi Variant) o interfacce, né possono essere strutturati tipi contenenti stringhe lunghe, array dinamici, varianti o interfacce ; ma possono essere indicatori di questi tipi.

I record con le parti varianti sono sintatticamente complicati ma in modo apparentemente semplice semanticamente. La parte variante di un record contiene diverse varianti che condividono lo stesso spazio in memoria.Puoi leggere o scrivere in qualsiasi campo di qualsiasi variante in qualsiasi momento; ma se si scrive su un campo in una variante e quindi su un campo in un'altra variante, è possibile che sovrascriva i propri dati. Il tag, se presente, funziona come un campo aggiuntivo (di tipo ordinalType) nella parte non variante del record .


Per il resto, è abbastanza di routine: LONGLONG è un intero a 64 bit e UCHAR è unsigned char, o AnsiChar in Delphi.

type 
    TFileObjectIDInformation = record 
    FileReference: Int64; 
    ObjectID: array[0..15] of AnsiChar; 
    case Integer of 
    0: 
     (
     BirthVolumeId: array[0..15] of AnsiChar; 
     BirthObjectId: array[0..15] of AnsiChar; 
     DomainId: array[0..15] of AnsiChar; 
    ); 
    1: 
     (ExtendedInfo: array[0..47] of AnsiChar); 
    end; 

E 'possibile che Byte può essere più adatto di AnsiChar. È un po 'difficile da dire, naturalmente, perché C, a differenza di Pascal, non ha tipi separati per Byte e AnsiChar. Ma questi array mi sembrano come se fossero letti come testo, quindi la mia ipotesi è che AnsiChar sarebbe più appropriato.

+0

+1 per la spiegazione di "C Unione";) –

+0

@David_Heffernan, Grazie. – Astaroth

+0

@Astaroth Fatto. Grazie. Sono sempre confuso da ciò! –

4

Simile struttura si possono trovare in JEDI API Lib:

_FILE_OBJECTID_BUFFER = record 

    // 
    // This is the portion of the object id that is indexed. 
    // 

    ObjectId: array [0..15] of BYTE; 

    // 
    // This portion of the object id is not indexed, it's just 
    // some metadata for the user's benefit. 
    // 

    case Integer of 
     0: (
     BirthVolumeId: array [0..15] of BYTE; 
     BirthObjectId: array [0..15] of BYTE; 
     DomainId: array [0..15] of BYTE); 
     1: (
     ExtendedInfo: array [0..47] of BYTE); 
    end; 
+0

Questa è una struttura diversa. Dai un'occhiata ai nomi. Quella struttura differisce in quanto non ha il primo campo che può essere trovato nella domanda. –

+0

@DavidHeffernan: mio stupido errore ... Ho modificato la risposta in qualche modo ... –

Problemi correlati