将结构从C转换为Delphi

Flz*_*Flz 7 c delphi type-conversion data-structures

我正在为一个delphi单元转换一个C头.我对联盟感到怀疑.例如,在下面的示例中,应用的逻辑是什么(CASE INTEGER OF)?这是转换此结构的正确方法吗?

在C.

typedef union _FLT_PARAMETERS {

    struct {
        PIO_SECURITY_CONTEXT SecurityContext;
        ULONG Options;
        USHORT POINTER_ALIGNMENT FileAttributes;
        USHORT ShareAccess;
        ULONG POINTER_ALIGNMENT EaLength;
        PVOID EaBuffer;                
        LARGE_INTEGER AllocationSize;  
    } Create;

    struct {
        PIO_SECURITY_CONTEXT SecurityContext;
        ULONG Options;
        USHORT POINTER_ALIGNMENT Reserved;
        USHORT ShareAccess;
        PVOID Parameters; // PNAMED_PIPE_CREATE_PARAMETERS
    } CreatePipe;

    ...
Run Code Online (Sandbox Code Playgroud)

在德尔福

   TCreate = record
        SecurityContext: PIO_SECURITY_CONTEXT;
        Options: ULONG;
        FileAttributes: USHORT;
        ShareAccess: USHORT;
        EaLength: ULONG;
        EaBuffer: PVOID;                 
        AllocationSize: LARGE_INTEGER; 
   end;

   TCreatePipe = Record
        SecurityContext: PIO_SECURITY_CONTEXT;
        Options: ULONG;
        Reserved: USHORT;
        ShareAccess: USHORT;
        Parameters: PVOID; 
   end;    

   _FLT_PARAMETERS = Record
     case integer of
       0: (Create: TCreate); 
       1: (CreatePipe: TCreatePipe):
   ...
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 4

这是转换该结构的正确方法吗?

联盟的翻译正确。您的 Pascal 变体记录是处理联合的正确方法。记录的变体部分与 C 联合的处理方式相同。来自文档中:

具有变体部分的记录在语法上很复杂,但在语义上却看似简单。记录的变体部分包含共享内存中相同空间的多个变体。您可以随时读取或写入任何变体的任何字段;但是,如果您写入一种变体中的字段,然后写入另一种变体中的字段,则可能会覆盖您自己的数据。


我在你的代码中看到的唯一问题是宏POINTER_ALIGNMENT。该宏扩展为什么?我的期望是它将扩展到__declspec(align(4))32 位代码和__declspec(align(8))64 位代码。

假设猜测是正确的,那么在编译 32 位时,您的 Delphi 代码将已经具有正确的布局。这是因为每个标记为 的字段POINTER_ALIGNMENT都已经被放置在 4 字节边界上。

但对于 64 位,记录将无法正确排列。如果您的目标是 64 位,则必须添加一些额外的填充,因为每个成员都标记为POINTER_ALIGNMENT都会被错误地布局。不幸的是,Delphi 中没有等效的功能,__declspec(align(#))因此您需要手动添加填充。

如果您确实需要添加此填充,您应该非常仔细地检查 C 和 Delphi 版本是否具有相同的布局。检查每个字段的偏移量是否匹配。