2013-11-15 167 views
3

我有將字節數組轉換爲結構的問題,有些字節會被忽略或跳過。C:將字節數組轉換爲struct

鑑於下面的結構,

typedef struct 
{ 
    uint32_t id; 
    uint16_t test; 
    uint8_t group; 
    uint32_t time; 
    uint16_t duration; 
    uint8_t a; 
    uint8_t b; 
    uint8_t c; 
    uint16_t d; 
    uint16_t e; 
    uint8_t status; 
    uint8_t x; 
    uint8_t y; 

} testStruct_t, *PtestStruct_t; 

我有下面的測試數據的數組:在

PtestStruct_t pStruct = (PtestStruct_t)pBuff; 

某處:

uint8_t pBuff = { 0x11 , 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 }; 

的鑄造作爲進行如下結構中一些字節被跳過或忽略。我不知道爲什麼。 這已經在Visual Studio 2012和需要此測試和調試的ARM處理器上進行了測試。

我在這裏錯過了什麼?我不相信這是Endian相關的。它可能是兩個測試用例中的編譯器,我不知道在最後一種情況下該怎麼做。

其被跳過忽略的字節數/有0x880x14

+3

maaping struct to binary format can be made without care。你應該閱讀'padding'和'alignment'和(壞消息,它是編譯器/處理器特定的) – Bruce

+1

如果你按照這裏所做的那樣做,它最好是一個平臺和依賴於實現的解決方案,並且可能是錯誤的無論如何(當你發現)。這兩個實現相關的填充和對齊將影響您要找的結果。 – WhozCraig

+0

通常有一個編譯器指令或#pragma來指定結構填充和對齊。 #pragma pack(0)或者gcc選項-fpack-struct [= n]有幾種控制方法。 Visual Studio在GUI中也有一個選項來爲你的項目設置結構填充。 –

回答

8

您遇到對齊填充。

uint32_t id;  // offset 0 
uint16_t test; // offset 4 
uint8_t group; // offset 6 
uint32_t time; // offset 7 

這裏顯示的偏移量可能是錯誤的。編譯器可能會在「組」和「時間」之間放置填充以確保「時間」位於4字節邊界上(實際對齊是可配置的)

如果您絕對需要這種結構,那麼您可以使用#pragma pack

#pragma pack(push, 1) 
typedef struct 
{ 
    uint32_t id; 
    uint16_t test; 
    uint8_t group; 
    uint32_t time; 
    uint16_t duration; 
    uint8_t a; 
    uint8_t b; 
    uint8_t c; 
    uint16_t d; 
    uint16_t e; 
    uint8_t status; 
    uint8_t x; 
    uint8_t y; 

} testStruct_t, *PtestStruct_t; 
#pragma pack(pop) 
+7

請注意,即使在1字節打包(仍然*必須*符合硬件對齊要求)之後,您仍然依賴於多字節縮放器的永久性。 – WhozCraig

+0

非常感謝:),非常感謝 – Armandt

1

編譯器可能已經對準你的結構域之間添加了一些字節。 你需要使用一個包裝,以防止編譯器做填充 - 這必須明確要求 - 在GCC它屬性((包裝)),

例如:

 struct __attribute__((__packed__)) mystruct_A { 
     char a; 
     int b; 
    char c; 
    }; 

和Visual Studio諮詢MSDN