我在代码之外的某处定义了C结构。我可以定义相同结构的打包版本吗?如果我从一开始就定义自己的结构,那很容易:
struct test {
// members
} __attribute__((packed));
我定义了一个简单的结构并尝试了两种可能性:
struct test {
int x;
double y;
char z;
};
struct test_p {
struct test __attribute__((packed)) s;
};
和此:
struct test {
int x;
double y;
char z;
};
struct test_p {
struct test p;
} __attribute__((packed));
然而,这些都没有(虽然编译都很好)在我的系统上打印sizeof(struct test_p)= 24(我在64位机器上使用gcc 4.8.2),这与sizeof(struct test)相同。有没有办法达到预期的效果?
以防你想知道:我想解析通过网络收到的只是打包结构的数据包。问题是,我无法修改头文件,因为它是第三方库的一部分,结构本身包含太多字段,无法逐个复制它们。我当然可以将结构定义复制到我自己的标题中并制作打包版本 - 实际上它是我现在使用的解决方案 - 但我只是想知道是否有一个更简洁的解决方案,不涉及复制整个定义。
答案 0 :(得分:1)
gcc已经将__attribute__((packed))
精确地引入避免你正在寻找的危险效果:结构的定义应该在所有用户应用程序和使用相同定义的库之间进行二进制兼容
但是gcc还提供了一种打包the old fashioned, dangerous way - #pragma pack(push,n)
和#pragma pack(pop)
的方法。仅当第三方头文件仅包含结构定义,或者您不使用标头中的任何其他内容时,它才能可靠地工作。像这样使用它们:
#pragma pack(push,1)
#include "theheader.h"
#pragma pack(pop)
否则,我个人只需复制粘贴结构定义,重命名它,并在我自己的标题中添加__attribute__((packed))
。用pragma包装整个标题实际上是一个肮脏的黑客。第三方标题可能会以意想不到的方式发生变化,从而导致the bit rot。