了解Ada如何序列化记录

时间:2020-03-05 18:59:12  来源:igfitidea点击:

我希望能够预测当我调用Ada中的Write来序列化记录时所生成的二进制文件中的内容。你知道我可以在哪里查找吗?

我有一些旧的Ada软件,可以通过写记录来生成二进制文件,并且需要调试应该编写兼容二进制文件的C ++程序。因此,我想了解Ada序列化记录时遵循的规则,以便可以确保C ++代码将生成功能上等效的记录。

解决方案

回答

Ada95语言参考手册说(第13.13.2节):

"对于基本类型,流元素的表示形式是实现定义的。对于复合类型,每个组件的Write或者Read属性均按规范顺序调用。组件的规范顺序是数组的最后维变化最快,并且记录的位置汇总顺序。"

回答

基本上,除非我们对记录类型使用pragma PACK或者pragma PRESERVE_LAYOUT命令,否则编译器基本上会重新排序记录类型的组件。同样,编译器将填充对象以保持记录组件的对齐。组件如下:

整数:8位,16位或者32位二进制补码带符号数字

浮点数:32位IEEE格式

Long_Float:64位IEEE格式

定点:8、16或者32位;但是,指定的范围和增量可能会影响16或者32

枚举:整数,通常第一个元素由0表示

布尔值:枚举对象,长8位,LSB存储值:0 =否,1 =正确

字符:枚举对象,长8位,无符号0到127

访问类型:32位,32位值为0表示NULL

数组:以行优先顺序连续存储,大小取决于基本类型。对数组进行填充以确保所有元素对其类型具有正确的对齐方式。

回答

就像其他人提到的那样,编译器将在没有其他指令的情况下就记录布局做出自己的决定。最好的方法是更改​​原始代码,以使用特定的布局写记录。特别是,记录表示子句使Ada程序员可以精确地指定记录的物理布局。实际上,我们应该检查原始代码中是否包含针对所讨论类型的其中一种代码。如果是这样,那么这将准确回答问题。

回答

'Write'的序列化输出的格式与表示子句完全无关。

默认情况下,编译器将使用标准未定义的转换方案,按照记录声明中写入记录的顺序输出记录组件,而无需对齐填充(因此,编译器之间可能无法实现互操作性)。 GNAT(GCC Ada编译器)以整数个字节输出每个组件。

如果我们要使用其他不同的格式流式传输类型的值,则可以覆盖该类型的"写入"。作为一个不寻常的示例,我们可以流式传输到XML。