在Java中复制C struct padding

Leh*_*ane 4 c java compiler-construction padding

根据这里,C编译器将在将结构写入二进制文件时填充值.正如链接中的示例所示,在编写这样的结构时:

struct {
 char c;
 int i;
} a;
Run Code Online (Sandbox Code Playgroud)

对于二进制文件,编译器通常会在char和int字段之间留下未命名的未使用的孔,以确保int字段正确对齐.

我怎样才能使用不同的语言(在我的例子中,Java)创建二进制输出文件(在C中生成)的精确副本?

是否有自动方式在Java输出中应用C填充?或者我是否必须通过编译器文档来了解它是如何工作的(顺便说一句,编译器是g ++).

sta*_*lue 14

不要这样做,它很脆,会导致对齐和字节序错误.

对于外部数据,最好使用shift和掩码(不是union!)以字节方式显式定义格式并编写显式函数以在内部和外部格式之间进行转换.

  • @Preet Sangha不,这是关于二进制格式的. (3认同)

unw*_*ind 8

这不仅适用于写入文件,也适用于内存.事实上,如果结构是逐字节写出的,那么结构被填充在内存中,导致填充显示在文件中.

通常很难确切地复制确切的填充方案,虽然我猜一些启发式方法会让你走得很远.如果你有结构声明,它有帮助进行分析.

通常,大于一个字符的字段将对齐,以便它们在结构内的起始偏移量是其大小的倍数.这意味着shorts通常在偶数偏移上(可以被2整除,假设sizeof (short) == 2),而doubles将在可被8整除的偏移上,依此类推.

更新:出于这样的原因(以及与endianness有关的原因),将整个结构转储到文件通常是个坏主意.最好逐场进行,如下所示:

put_char(out, a.c);
put_int(out, a.i);
Run Code Online (Sandbox Code Playgroud)

假设put-functions只写入值所需的字节,这将向文件发出一个无填充版本的结构,解决了这个问题.通过相应地编写这些函数,还可以确保正确的,已知的字节排序.


Mic*_*rdt 5

是否有自动方式在Java输出中应用C填充?或者我是否必须通过编译器文档来了解它是如何工作的(顺便说一句,编译器是g ++).

都不是.相反,您明确指定数据/通信格式并实现该规范,而不是依赖于C编译器的实现细节.您甚至不会从不同的C编译器获得相同的输出.