2013-11-15 2 views
3

У меня возникла проблема приведения байтового массива в структуру, некоторые байты игнорируются или пропускаются.C: Массив байтового массива для структуры

Учитывая следующую структуру,

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; 

У меня есть массив со следующими данными тест:

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 }; 

Отливка производится следующим образом:

PtestStruct_t pStruct = (PtestStruct_t)pBuff; 

Где-то в структура некоторых байтов пропускается или игнорируется. Я не знаю почему. Это было протестировано в Visual Studio 2012 и на процессоре ARM, на котором было выполнено это тестирование и отладка.

Что мне здесь не хватает? Я не верю, что это связано с Эндией. Это может быть компилятор в обоих тестовых случаях, я не знаю, что делать в этом последнем случае.

байт, которые пропуск/игнорировали являются 0x88 и 0x14

+3

Невозможно сделать maaping struct в двоичном формате без забот. Вы должны прочитать о 'padding' и' alignment' и (плохие новости, это компилятор/процессор) – Bruce

+1

Если вы делаете это как показано здесь, это уже в лучшем случае решение для платформы и реализации, и, вероятно, неправильное в любом случае (как вы открываете). Зависимые от реализации дополнения и выравнивания будут влиять на результат, который вы ищете. – WhozCraig

+0

обычно указывается директива компилятора или #pragma для указания заполнения и выравнивания структуры. #pragma pack (0) или опция gcc -fpack-struct [= n] - это несколько способов контроля этого. В Visual Studio также есть опция в графическом интерфейсе, чтобы установить дополнение структуры для вашего проекта. –

ответ

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

Компилятор может быть добавлен некоторый байт между вашими STRUCT полями для выравнивания. Вы должны использовать упаковку, чтобы не позволяет компилятору делать отступы - это должно быть явно просил - под GCC это атрибут ((упакована)),

пример:

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

и Visual Studio обратитесь к MSDN

Смежные вопросы