如何将C语言的联合体(union)转换成Delphi?

3
我正在将C库转换为Delphi。 我在转换以下代码时遇到了问题。 这是用于通信的结构体,因此顺序必须正确。
Tparam_union_params_t = packed record
  case Integer of
    0: (param_float:single);
    1: (param_int32:Int32);
    2: (param_uint32:UInt32);
    ...
    ...
end;

Tparam_union_t = packed record
  param:Tparam_union_params_t // This method requires var name.
  type:UInt8;
end;

C语言

#ifdef __GNUC__
  #define PACKED( __Declaration__ ) __Declaration__ __attribute__((packed))
#else
  #define PACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
#endif

PACKED(
typedef struct param_union {
    union {
        float param_float;
        int32_t param_int32;
        uint32_t param_uint32;
        int16_t param_int16;
        uint16_t param_uint16;
        int8_t param_int8;
        uint8_t param_uint8;
        uint8_t bytes[4];
    }; // This no-named union. no-named is important.
    uint8_t type;
}) param_union_t;

我的方法需要变量名,但原始的 C 代码没有命名。我该如何将 C 中的匿名联合或结构体转换为 Delphi?

1个回答

6
你所拥有的并不错,但在我的文章中《转换陷阱》中,我描述了一种更好的处理无名称联合体的技巧。
param_union_p = ^param_union_t;
param_union_t = packed record
  case Integer of
    0: (param_float: Single);
    1: (param_int32: Int32);
    2: (param_uint32: UInt32;    // add the members after the union to the largest branch.
        &type: UInt8);
    3: (param_int16: Int16);
    ...
    ...
end;
PParamUnion = ^TParamUnion;
TParamUnion = param_union_t;

可以将代码添加到与UInt32大小相同的SingleInt32分支中,而不是在UInt32分支中。这仍将导致与C结构中相同的内存布局,其中&type在偏移4处,记录的大小为5,这就是所有的内容。请参阅文章中的图表以进行澄清:

enter image description here

这样,就不需要为联合部分提供自己的类型和名称。如果您不信任这个“技巧”,请使用我在同一篇文章中提供的代码来检查C和Delphi中的偏移量。

Borland、Embarcadero和Delphi-JEDI也使用了相同的技巧来翻译匿名联合,Delphi TVarRec(用于array of const参数)和TVarType(用于变体)记录也是这样构建的。


谢谢!我有一个问题关于你的代码。为什么要使用指针param_union_p和PParamUnion?我想了解一下,因为我缺乏经验。 :) - Seunghyun Baek
我已经转换了许多API头文件,通常声明指针类型和漂亮的(类似Delphi的)名称也很有意义,例如不使用下划线和驼峰式命名。在C和C++中,_t后缀通常与Delphi中的T前缀具有相同的含义,因此对于一个指针,我使用_p后缀,就像在Delphi中使用P前缀一样。像 PSomething = ^TSomething;这样的行在这种翻译中非常常见。 - Rudy Velthuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接