我想在没有任何外部库的情况下仅使用标准 C 来读取、编辑和写入 bmp 文件。
如果我理解正确,重要的是正确对齐字节以匹配 bmp 文件格式。
但是,我想我也在互联网上的某个地方读到允许编译器填充struct
额外的字节,所以我不能总是确定我的结构占用了多少字节,甚至不能确定成员在结构中是如何对齐的。
如何仅使用标准 C 来解决此问题?是否有语法要求编译器确保我的结构看起来完全符合我指定的方式?
如何仅使用标准 C 来解决此问题?是否有语法要求编译器确保我的结构看起来完全符合我指定的方式?
C 标准没有提供控制结构布局的标准方法。因此,如果您只使用标准指定的内容,则不能使用结构来处理 Windows 位图文件。
要使用标准 C 解决此问题,您需要自己编写/读取字节数组并对其进行序列化/反序列化。
正如 Kninnug 在评论中所说,BMP 格式旨在与 C 结构类型兼容。无论出于何种原因,AC 编译器都可以在任意两个结构成员之间或最后一个成员之后随意插入尽可能多的填充 - 但在现实生活中,编译器仅在对齐所需的位置插入填充,并且通常符合到平台的书面 ABI。
您可以使用offsetof
宏和sizeof
运算符进行测试,但不能指定结构类型的布局——这对于您的目的可能已经足够了。
例如,如果您想要一个符合外部强加布局的结构,该布局由一个 32 位无符号整数、一个 16 位无符号整数和两个 8 位无符号整数组成,按此顺序分配总共 64 位,你可以这样写:
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
struct s {
uint32_t a;
uint16_t b;
uint8_t c;
uint8_t d;
};
void test_layout(void) {
assert(offsetof(struct s, a) == 0);
assert(offsetof(struct s, b) == 4);
assert(offsetof(struct s, c) == 6);
assert(offsetof(struct s, d) == 7);
assert(sizeof (struct s) == 8);
}
test_layout()
程序启动时调用该函数;如果您的程序能够幸存下来,则可以确保布局是正确的。
好吧,几乎 - 测试字节顺序留作练习。