我正在为字体创建一个4位和8位颜色编码。这包括前景,背景,样式和格式。我希望使用以下结构来表示4字节包中的数据。我的目的是将其提取为单个uint32_t
,可以将其转换为二进制数据并保存在文件中。
这就是我目前所拥有的:
struct font_pack {
uint8_t : 8;
struct {
uint8_t format : 4;
uint8_t style : 4;
} header;
uint8_t foreground;
uint8_t background;
}
标头包含两个半字节。 format
表示颜色代码为4位或8位颜色。 style
是一个标志集,用于声明格式化程序,例如粗体和下划线。
然后我使用以下union
来获取写入文件的原始二进制文件,以及将数据设置或打印为十六进制。
union font_raw {
font_pack pack;
uint32_t data;
}
不幸的是,当我打印出十六进制时,我期待0x04032100
时得到0x00120304
。这让我觉得在union
内不能保证字节对齐,并且字节顺序正在抓住我。我真的只是希望有简单的打包方法,并将数据打包成3个字节。
有没有其他简单的方法可以做到这一点,还是我坚持做一个更传统的功能来打包和拆包?
答案 0 :(得分:1)
这肯定是一个字节序问题。我猜你是在x86 / x64(类似英特尔)架构上,这是一个小端,并且会将字节从最不重要到最重要。如果您正在相同的体系结构上编写和读取数据(那么小端系统),字节顺序将确保您以相同的顺序读回字节包装,因此您的font_pack
成员仍应正确显示。但是,如果您要在big-endian系统上加载这些文件,则需要采用更传统的路线。但是,如果你保证同样的endian-ness,我会选择你的方法。这很优雅:))
编辑:如果您 在不同的字节顺序机器之间进行读取或写入,那么您可以始终执行以下操作:
#ifdef LITTLE_ENDIAN
struct font_pack {
uint8_t : 8;
struct {
uint8_t format : 4;
uint8_t style : 4;
} header;
uint8_t foreground;
uint8_t background;
}
#else
struct font_pack {
uint8_t background;
uint8_t foreground;
struct {
uint8_t format : 4;
uint8_t style : 4;
} header;
uint8_t : 8;
}
#endif
然后在x86或类似系统上定义LITTLE_ENDIAN,而不是在big-endian系统上定义。希望有所帮助。