2012-11-10 50 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; 

如何将这样的联合转换为Delphi?如何将C union翻译成Delphi?

回答

19

C union的帕斯卡当量被称为variant record

记录类型可以有一个变体部分,它看起来像一个情况 声明。变体部分必须遵循记录 声明中的其他字段。

要使用的变体部分声明的记录类型,使用以下 语法:

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

声明的第一部分 - 高达保留字情况 - 是 相同的一个标准的记录类型。 声明的其余部分 - 从case到可选的最终分号 - 被称为 变体部分。在变体部分中,

  • 标记是可选的,可以是任何有效的标识符。如果您省略了标记,那么也应该省略冒号(:)。
  • ordinalType表示序数类型。
  • 每个constantList是一个常量,表示类型为ordinalType的值,或者这些常量的逗号分隔列表。在组合的常数列表中, 可以不止一次表示值。
  • 每个变体是声明颇似fieldList中的分号分隔的列表:类型构造在 记录类型的主要部分。也就是说,变体的形式如下:

    fieldList1:type1; ... fieldListn:typen;

其中每个fieldList中是有效的标识符或 标识符逗号分隔的列表,其中每个类型表示一种类型,并且最终分号是 可选的。类型不能是长字符串,动态数组,变体 (即变体类型)或接口,也不能是包含长字符串,动态数组,变体或接口的 类型的结构体;但它们可以是指向这些类型的指针。

变体部分的记录在语法上是复杂的,但是在语义上看起来很简单 。记录的变体部分包含 几个在内存中共享相同空间的变体。您可以在任何时间阅读或写入任何变体的任何字段;但如果您在一个变体中写入 字段,然后写入另一个变体中的字段,则可能会覆盖您自己的数据。该标记(如果存在的话)在 记录的非变体部分中起到 附加字段(类型ordinalType)的作用。


至于其他的,这是很常规:LONGLONG是一个64位整数,UCHARunsigned char,或在Delphi 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可能比AnsiChar更合适。当然有点难以分辨,因为与Pascal不同,C不具有ByteAnsiChar的单独类型。但是这些数组看起来好像他们会被读作文本,所以我猜想AnsiChar会更合适。

+0

1为 “C联盟” 的说明) –

+0

@David_Heffernan,感谢。 – Astaroth

+0

@Astaroth完成。谢谢。我总是感到困惑! –

4

类似结构可以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

这是一个不同的结构。看看这些名字。该结构的不同之处在于它没有可以在问题中找到的第一个字段。 –

+0

@DavidHeffernan:我的愚蠢的错误...我以某种方式编辑了答案...... –