2014-08-29 61 views
3

我有一个C结构定义在我的代码之外的某处。我可以定义相同结构的打包版本吗?如果我从一开始就定义自己的结构,即简单:定义打包版本的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)); 

但是,在我的系统上(我在64位机器上使用gcc 4.8.2)与sizeof(struct test)相同,这两种工作都无法正常工作(都编译得很好),所以打印sizeof(struct test_p)= 24。有没有办法达到预期的效果?

以防万一你想知道:我想解析通过网络收到的只是打包结构的数据包。问题是,我无法修改头文件,因为它是第三方库的一部分,并且结构本身包含太多字段以逐一复制它们。我当然可以将结构定义复制到我自己的头文件中并制作压缩版本 - 实际上它是我现在使用的解决方案 - 但我只是想知道是否有一个更简洁的解决方案,它不涉及复制整个定义。

+0

一个有趣的问题,但我不认为你会找到一个优雅的解决方案; “您只能在枚举,结构或联合的定义上指定此属性,而不能在不定义枚举类型,结构或联合的typedef上指定此属性。” https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html – Dave 2014-08-29 07:28:54

回答

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))。包装与杂记整个标题是一个肮脏的黑客。第三方标题可能会以意想不到的方式发生变化,为the bit rot做出贡献。