在内存中打包结构体以及与 DLL 交互
要存储结构体的一个实例,需要在内存中分配一个足以容纳所有元素的连续区域。
与 C++ 不同的是,这里的结构体元素在内存中连续排列,不会根据元素本身的大小在 2、4、8 或 16 字节的边界上对齐(不同的编译器和运行模式有不同的对齐算法)。如果元素的大小小于指定的块,则通过在结构体组成中添加未使用的虚拟变量(程序无法直接访问这些变量)来对元素进行对齐。对齐用于优化内存性能。
MQL5 允许您在必要时更改对齐规则,主要是在将 MQL 程序与描述特定类型结构体的第三方 DLL 集成时。对于这些第三方 DLL,需要在 MQL5 中准备等效说明(参见有关 导入库的章节)。需要注意的是,用于集成的结构体在其定义中只能包含有限类型的字段。因此,它们不能使用字符串、动态数组以及类对象和指向类对象的 指针 。
对齐方式由添加到结构体头部的 pack 关键字控制。有两个选项:
struct pack(size) identifier
|
在这两种情况下,大小都是整数 1、2、4、8、16。或者使用 sizeof(built-in_type) 运算符作为大小,例如 sizeof(double)。
选项 pack(1),即字节对齐,与不带 pack 修饰符的默认行为相同。
通过特殊运算符 offsetof(),可以找出特定结构体元素从其起始位置开始的字节偏移量。它有两个参数:结构体对象和元素标识符。例如,
Print(offsetof(Result, status)); // 36 |
在 Result 结构体的 status 字段之前,有 4 个 double 值和 1 个 int 值:总共 36 个字节。
在设计自己的结构体时,建议先放置最大的元素,然后按大小递减的顺序放置其余元素。