了解 Ada 如何序列化记录
当我调用 Ada 中的 Write 来序列化记录时,我希望能够预测生成的二进制文件中的内容。 你知道我可以在哪里查到这个吗?
我有一些遗留的 Ada 软件,可以通过写入记录来生成二进制文件,并且我需要调试一个应该编写兼容的二进制文件的 C++ 程序。 因此,我想了解 Ada 在序列化记录时遵循哪些规则,以便我可以确保 C++ 代码将生成功能等效的记录。
I would like to be able to predict what will be in the resulting binary when I call Write in Ada to serialize a record. Do you know where I can look this up?
I have some legacy Ada software that produces a binary file by Write-ing a record, and I need to debug a C++ program that is supposed to write a compatible binary file. So, I would like to understand what rules Ada follows when it serializes a record, so that I can make sure that the C++ code will produce a functionally equivalent record.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
基本上,编译器将对记录类型的组件重新排序,除非您对记录类型使用 pragma PACK 或 pragma PRESERVE_LAYOUT 命令。 此外,编译器将填充对象以保持记录组件的对齐。 组件如下:
整数:8、16 或 32 位二进制补码有符号数
浮点:32 位 IEEE 格式
Long_Float:64 位 IEEE 格式
定点:8、16 或 32 位; 但是,指定的范围和增量可能会影响为 16 或 32
枚举:整数,通常第一个元素由 0 表示
布尔值:枚举对象,8 位长,LSB 存储值:0 = false,1 = true
字符:枚举对象,8 位长,无符号 0 到 127
访问类型:32 位,32 位值 0 表示 NULL
数组:按行优先顺序连续存储,大小取决于基本类型。 该数组被填充以确保所有元素都与其类型正确对齐。
Basically, the compiler will reorder the components of your record types, unless you use the pragma PACK or the pragma PRESERVE_LAYOUT commands with your record types. Also, the compiler will pad objects to maintain the alignment of record components. Components follow:
Integer: 8, 16, or 32 bit twos-complement signed numbers
Float: 32-bit IEEE format
Long_Float: 64-bit IEEE format
Fixed-Point: 8, 16, or 32 bit; however, the range and delta specified can affect being 16 or 32
Enumerations: Integer, usually first element is represented by 0
Booleans: Enumeration object, 8 bits long, The LSB stores the value: 0 = false, 1 = true
Characters: Enumeration object, 8 bits long, unsigned 0 through 127
Access Types: 32 bits, 32-bit value of 0 represents NULL
Arrays: stored contiguously in row-major order, size depends on base type. The array is padded to ensure all elements have the proper alignment for their types.
“Write”的序列化输出的格式与表示子句绝对无关。
默认情况下,编译器将按照记录声明中写入的顺序输出没有对齐填充的记录组件,使用标准未定义的转换方案(因此您可能无法获得编译器之间的互操作性)。 GNAT(GCC Ada 编译器)以整数字节输出每个组件。
如果您想使用某种不同的格式流式传输某个类型的值,您可以覆盖“Write for the type”。 作为一个不寻常的示例,您可以流式传输到 XML。
The format of the serialised output of 'Write has absolutely nothing to do with representation clauses.
By default, the compiler will output record components without alignment padding in the order in which they're written in the record declaration, using a translation scheme that isn't defined by the standard (so you may not get interoperability between compilers). GNAT (the GCC Ada compiler) outputs each component in a whole number of bytes.
If you want to stream values of a type using some different format, you can override 'Write for the type. As an unusual example, you could stream to XML.
正如其他人所提到的,如果没有额外的指令,编译器将自行决定记录布局。 最好的方法是更改原始代码以使用特定布局写入记录。 特别是,记录表示子句允许 Ada 程序员准确指定记录的物理布局。 事实上,您应该检查原始代码是否具有针对相关类型的其中之一。 如果确实如此,那么这将准确回答您的问题。
As mentioned by others, without additional instruction the compiler will make its own decisions about record layout. The best approach would be to change the original code to write the record using a specific layout. In particular, the record representation clause allows the Ada programmer to specify exactly the physical layout for a record. In fact, you should check to see whether the original code has one of these for the type in question. If it does, then this would answer your question precisely.
Ada95 语言参考手册 说(第 13.13.2 节):
“对于基本类型,流元素的表示是由实现定义的,每个组件的写入或读取属性都按规范顺序调用。记录。”
The Ada95 Language Reference Manual says (section 13.13.2):
"For elementary types, the representation in terms of stream elements is implementation defined. For composite types, the Write or Read attribute for each component is called in a canonical order. The canonical order of components is last dimension varying fastest for an array, and positional aggregate order for a record."