强制C++结构紧密封装

Force C++ structure to pack tightly

本文关键字:密封 封装 结构 C++ 强制      更新时间:2023-10-16

我正在尝试读取一个二进制文件。问题是,文件的创建者没有花时间将数据结构与其自然边界正确对齐,而且一切都很紧凑。这使得使用C++结构读取数据变得困难。

有没有办法迫使struct包装紧密?

示例:

struct {
short a;
int b;
}

上面的结构是8个字节:short a为2,填充为2,int b为4。然而,在磁盘上,数据只有6个字节(没有用于对齐的2个字节的填充)

请注意,实际的数据结构是数千个字节和许多字段,包括几个数组,所以我不希望单独读取每个字段。

如果您使用GCC,您可以执行struct __attribute__ ((packed)) { short a; int b; }

在VC++上,您可以执行#pragma pack(1)。GCC也支持此选项。

#pragma pack(push, 1)
struct { short a; int b; }
#pragma pack(pop)

其他编译器可以选择在没有填充的情况下对结构进行紧密封装。

您需要使用编译器特定的非标准指令来指定1字节的打包。例如在Windows:下

#pragma pack (push, 1)

问题是文件的创建者没有花时间字节对齐数据结构,一切都很紧凑。

实际上,设计师做了正确的事情。填充是标准规定可以应用的东西,但没有说明在什么情况下应该应用多少填充。标准甚至没有说明一个字节中有多少位。尽管你可能会认为,即使这些东西没有被指定,它们在现代机器上仍然应该是相同的合理价值,但事实并非如此。例如,在32位Windows机器上,填充可能是一回事,而在64位版本的Windows上,填充则可能是另一回事。也许情况会一样——这不是重点。关键是你不知道在不同的系统上会有什么填充。

因此,通过"紧密地包装",开发人员做了他们唯一能做的事情——使用一些他可以合理确定每个系统都能理解的包装。在这种情况下,通常理解的打包是在保存到磁盘或通过导线发送的结构中不使用填充。