c - 如何将 C union 转换为 delphi?
问题描述
我正在将 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;
我的方法需要 var name 但原始 c 代码没有命名。如何将 C 中的匿名联合或结构转换为 Delphi?
解决方案
您所拥有的还不错,但是在我的文章转换的陷阱中,我描述了一种更好的技术来处理这种没有名称的联合:
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
分支中,它还可以添加到相同大小的Single
或分支中。Int32
这仍然会导致与 C 中的结构相同的内存布局,&type
偏移量为 4,记录的大小为 5,仅此而已。只需看一下文章中的图表即可进行澄清:
这样,就不需要给联合部分自己的类型和自己的名称。如果您不相信“技巧”,请使用我在同一篇文章中提供的代码来检查 C 和 Delphi 中的偏移量。
Borland 和 Embarcadero 以及 Delphi-JEDI 使用(d)相同的技巧来翻译匿名联合,并且 Delphi TVarRec
(用于array of const
参数)和TVarType
(用于变体)记录也是以这种方式构建的。
推荐阅读
- python - 创建一个多级饼图,其中外圆是 matplotlib 中内圆的子集
- ionic-framework - 在离子应用程序'模块''*''中导出到 excel 时生成错误没有导出的成员'
- typescript - 有没有办法只有一个 AWS APIGateway 请求来获取 AWS StepFunction 的输出?
- python - 将数据插入多个 SQL 表的 Python 脚本
- jquery - Newsignature 美国地图:悬停任何州时更改州填充
- javascript - 我的 Purge 命令有问题 (Discord.js)
- flutter - 颤振应用程序中的相机问题(> Android 不支持所选的 imageFormatGroup。默认为 yuv420)
- node.js - 动态发送剩余电子邮件节点js
- java - 如何使用父对象的构造函数创建子对象?(爪哇)
- python - 熊猫检查单元格值是否在另一个数据框的范围之间