Gcc 我可以使用并集和位字段进行数据打包吗

Gcc 我可以使用并集和位字段进行数据打包吗,gcc,c++14,Gcc,C++14,我正在为字体创建4位和8位颜色编码。这包括前景、背景、样式和格式。我希望使用以下结构来表示4字节数据包中的数据。我的目的是将其提取为单个uint32\t,可以转换为二进制数据并保存在文件中 这就是我目前拥有的: struct font_pack { uint8_t : 8; struct { uint8_t format : 4; uint8_t style : 4; } header; uint8_t foreground;

我正在为字体创建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;
}
标头包含两个半字节<代码>格式表示颜色代码为4位或8位颜色<代码>样式是一个位标志集,用于声明格式设置程序,如粗体和下划线

然后,我使用下面的
union
来获取写入文件的原始二进制文件,以及将数据设置为十六进制或打印为十六进制

union font_raw {
    font_pack pack;
    uint32_t data;
}
不幸的是,当我打印出十六进制时,我得到了
0x04032100
,而我期望的是
0x00120304
。这让我觉得字节对齐在
联合中是不可靠的,而且endianness正在吸引我。我真的只是希望有一个简单的方法来包装和解压成3字节的数据


还有其他简单的方法吗?或者我一直在做一个更传统的函数来完成打包和解包吗?

这看起来确实是一个持久性问题。我猜您使用的是x86/x64(类似英特尔)体系结构,它是小尾端,将从最低有效位到最高有效位打包字节。如果您在同一体系结构(如此少的endian系统)上写入和读取数据,endianness将确保您以相同的顺序读取字节压缩,因此您的
font\u pack
成员仍应正确显示。但是,如果要在big-endian系统上加载这些文件,则需要采用更传统的方法。但是如果你在同一个端点上,我会同意你的方法。非常优雅:)

编辑:如果您在不同的endianness机器之间进行读取或写入,则始终可以执行以下操作:

#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系统上。希望帮助。

什么是代码> SIEZOF(FuntPoPb)< /C>?使用C++标准<代码> UTI8*T 数据结构,<代码> futtPoxs是可靠的4字节。它完全符合工会的
uint32\t
。是什么让你认为它不起作用?我为字段分配了值,将数据保存到uint32,创建了一个新的字体,从uint32分配了数据,字段是正确的。为什么需要按照特定的顺序将其放入3个字节?为了将数据读写到二进制流,需要按照正确的顺序进行,否则字段将根据编译器和平台进行反转。因此,现在对我来说,十六进制输出的顺序与字体包的声明顺序相反。这是有道理的,我想如果你为一个特定的架构(即x86_64)编译,尽管它在物理硬件上运行,但endianness将得到保证。是的。但记住这一点并没有什么坏处,尤其是在编写跨平台代码时。我以前被这个咬过(有人吗?)