了解 Ada 如何序列化记录
-
01-07-2019 - |
题
当我调用 Ada 中的 Write 来序列化记录时,我希望能够预测生成的二进制文件中的内容。你知道我可以在哪里查到这个吗?
我有一些遗留的 Ada 软件,可以通过写入记录来生成二进制文件,并且我需要调试一个应该编写兼容的二进制文件的 C++ 程序。因此,我想了解 Ada 在序列化记录时遵循哪些规则,以便我可以确保 C++ 代码将生成功能等效的记录。
解决方案
正如其他人所提到的,如果没有额外的指令,编译器将自行决定记录布局。最好的方法是更改原始代码以使用特定布局写入记录。特别是, 记录表示子句 允许 Ada 程序员准确指定记录的物理布局。事实上,您应该检查原始代码是否具有针对相关类型的其中之一。如果确实如此,那么这将准确回答您的问题。
其他提示
'Write 的序列化输出的格式有 绝对没有 与表示条款有关。
默认情况下,编译器将按照记录声明中写入的顺序输出没有对齐填充的记录组件,使用标准未定义的转换方案(因此您可能无法获得编译器之间的互操作性)。GNAT(GCC Ada 编译器)以整数字节输出每个组件。
如果您想使用某种不同的格式流式传输某个类型的值,您可以覆盖“Write for the type”。作为一个不寻常的示例,您可以流式传输到 XML。
基本上,编译器将对记录类型的组件重新排序,除非您对记录类型使用 pragma PACK 或 pragma PRESERVE_LAYOUT 命令。此外,编译器将填充对象以保持记录组件的对齐。组件如下:
整数:8、16 或 32 位二进制补码有符号数
漂浮:32 位 IEEE 格式
长浮点:64 位 IEEE 格式
固定点:8、16 或 32 位;但是,指定的范围和增量可能会影响 16 或 32
枚举:整数,通常第一个元素用0表示
布尔值:枚举对象,8位长,LSB存储值:0 = 假,1 = 真
人物:枚举对象,8 位长,无符号 0 到 127
访问类型:32位,32位值为0代表NULL
数组:按行优先顺序连续存储,大小取决于基本类型。该数组被填充以确保所有元素都与其类型正确对齐。
这 Ada95 语言参考手册 说(第 13.13.2 节):
“对于基本类型,流元素的表示是实现定义的。对于复合类型,按规范顺序调用每个组件的 Write 或 Read 属性。组件的规范顺序是数组中变化最快的最后一个维度,以及记录的位置聚合顺序。”