2013-11-15 135 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