强制C++结构紧密封装
Force C++ structure to pack tightly
我正在尝试读取一个二进制文件。问题是,文件的创建者没有花时间将数据结构与其自然边界正确对齐,而且一切都很紧凑。这使得使用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上,填充则可能是另一回事。也许情况会一样——这不是重点。关键是你不知道在不同的系统上会有什么填充。
因此,通过"紧密地包装",开发人员做了他们唯一能做的事情——使用一些他可以合理确定每个系统都能理解的包装。在这种情况下,通常理解的打包是在保存到磁盘或通过导线发送的结构中不使用填充。
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将可变参数函数的参数封装在类实例中
- 带有 CKKS 的 Microsoft 密封中的矢量点积
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 封装C++模板
- 将 RTOS 队列对象封装在仅具有静态分配的 IQueue 自定义接口中
- 从封装在对象中的函数 C++ 返回时为空的列表
- 当要访问的对象被多次封装时,如何正确使用setter
- 在为嵌套类定义行外友元时,我真的必须打破封装吗?
- 如何在类中封装C/C++套接字发送和接收函数?
- 寻求提高Microsoft密封库计算效率的方法
- 如何使用吸气剂方法实现C++封装
- 封装 std::map 以允许迭代,但没有直接密钥访问?
- 类C++友元函数无法访问封装的类
- 当从成员类调用封装的std::begin时,程序崩溃
- 从私有成员类中断封装派生的模板类
- C++实用程序,用于将长开关语句转换为封装开关案例阶梯的简洁函数调用
- 如何修复列表视图中的错误?,封装控件时无法选择任何项
- 我们可以使用命名空间实现封装吗?
- 封装 std::vector 以允许迭代,但不允许其他内容