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

そのようなユニオンを Delphi に変換する方法は?

4

2 に答える 2

25

C に相当する Pascalはバリアント レコードunionと呼ばれます。

レコード タイプには、 case ステートメントのようなバリアント パーツを含めることができます。バリアント部分は、レコード宣言の他のフィールドの後に続く必要があります。

バリアント パーツを含むレコード タイプを宣言するには、次の構文を使用します。

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

宣言の最初の部分 (予約語caseまで) は、標準のレコード型と同じです。宣言の残りの部分 (ケースからオプションの最後のセミコロンまで) は、バリアント部分と呼ばれます。バリエーション部分では、

  • tagはオプションで、任意の有効な識別子にすることができます。tagを省略する場合は、その後のコロン (:) も省略します。
  • ordinalTypeは序数型を示します。
  • constantListは、型ordinalTypeの値を示す定数、またはそのような定数のコンマ区切りリストです。結合されたconstantListsで値を複数回表すことはできません。
  • バリアントは、 fieldListに似たセミコロンで区切られた宣言のリストです。レコード型の主要部分の型構造。つまり、バリアントの形式は次のとおりです。

    fieldList1: type1; ... fieldListn: typen;

ここで、各fieldListは有効な識別子またはコンマ区切りの識別子のリストであり、各タイプはタイプを示し、最後のセミコロンはオプションです。型は、長い文字列、動的配列、バリアント (つまり、バリアント型)、またはインターフェイスであってはならず、長い文字列、動的配列、バリアント、またはインターフェイスを含む構造化された型であってはなりません。ただし、それらはこれらの型へのポインターにすることができます。

バリアント パーツを含むレコードは、構文的には複雑ですが、意味的には一見単純です。レコードのバリアント部分には、メモリ内の同じスペースを共有するいくつかのバリアントが含まれています。任意のバリアントの任意のフィールドをいつでも読み書きできます。ただし、あるバリアントのフィールドに書き込み、次に別のバリアントのフィールドに書き込むと、独自のデータが上書きされる可能性があります。タグが存在する場合、そのタグは、レコードの非バリアント部分の( ordinalType型の) 追加フィールドとして機能します。


残りについては、かなり日常的です。LONGLONGは 64 ビット整数でありUCHAR、Delphiunsigned charでは 、 またはです。AnsiChar

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;

Byteよりも の方が適している可能性がありますAnsiCharByteC は Pascal とは異なり、との個別の型を持たないため、もちろん見分けるのは少し難しいAnsiCharです。AnsiCharしかし、これらの配列はテキストとして読み取られるように見えるので、そのほうが適切だと思います。

于 2012-11-10T17:46:43.453 に答える
5

同様の構造が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;
于 2012-11-10T17:50:45.540 に答える