2014-08-29 64 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做出貢獻。