2012-04-30 2 views
0

У меня есть проект Visual Studio 2008 C++, где мне нужно декодировать 6-байтовый массив данных в структуру.декодирование двоичных данных blob для структуры

Моя мысль была сделать что-то вроде этого:

#pragma pack(push, 1) 
struct Map 
{ 
    BYTE alpha : 8; 
    BYTE bravo : 8; 
    UINT charlie : 24; 
    BYTE delta : 8; 
    BYTE padding0 : 8; // ensure correct byte boundary 
    BYTE padding1 : 8; 
}; 
#pragma pack(pop) 
// sizeof(Map) == 8 bytes 

BYTE test_data[ 6 ] = { 0x07,  // alpha 
         0x0B,  // bravo 
         0x00,  // charlie high byte 
         0x00,  // charlie med byte 
         0x01,  // charlie low byte 
         0x33 }; // delta 
Map map = { }; 
memcpy(&map, test_data, sizeof(test_data)); 
ASSERT(map.alpha == 0x07); 
ASSERT(map.bravo == 0x0B); 
ASSERT(map.charlie == 0x01); 
ASSERT(map.delta == 0x33); 

Но, данные в charlie и delta никогда не бывает правильным.

Есть ли способ структурировать мою структуру, чтобы получить это правильно или я застрял в настройке каждого поля отдельно?

Thanks

+1

Вы смотрите, как вы только положить 3 байта в Чарли; для 32-битной платформы потребуется 4 байта. Кроме того, убедитесь, что ваша endianess правильная. –

ответ

1

Чтобы сделать это переносимым способом:

struct Map 
{ 
    BYTE alpha; 
    BYTE bravo; 
    UINT charlie; 
    BYTE delta; 

    Map(const BYTE data[6]) 
    : alpha(data[0]) 
    , bravo(data[1]) 
    , charlie((data[2] << 16) | (data[3] << 8) | data[4]) 
    , delta(data[5]) 
    {} 
}; 

int main() 
{ 
    BYTE test_data[ 6 ] = { 0x07,  // alpha 
       0x0B,  // bravo 
       0x00,  // charlie high byte 
       0x00,  // charlie med byte 
       0x01,  // charlie low byte 
       0x33 }; // delta 
    Map map(test_data); 
    ASSERT(map.alpha == 0x07); 
    ASSERT(map.bravo == 0x0B); 
    ASSERT(map.charlie == 0x01); 
    ASSERT(map.delta == 0x33); 
} 
0

Вы не можете наименовать типы соединений наивно. Просто напишите сам:

std::tuple<char, char, unsigned int, char> 
parse(char const * buf) 
{ 
    return std::make_tuple(buf[0], 
          buf[1], 
          buf[2] + 256 * buf[3] + 256 * 256 * buf[4], 
          buf[5]); 
} 

Конечно, вы должны соответствовать порядку байт целого числа к тому, что документируется вашим сериализованным форматом, мало-Endian в моем примере.

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