2017-01-23 22 views
1

Я часто сталкиваюсь с ситуацией, когда я получаю упакованные двоичные данные (т. Е. Где переменные не правильно выровнены) по протоколу, а данные обычно поступают в std :: string, std :: vector или какой-либо другой такой контейнер.Каков правильный способ инициализации переменной из двоичного буфера?

Мой вопрос в том, что является лучшей практикой для распаковки таких данных? Я обычно выполнить что-то вроде:

int32_t x = *((int32_t*)charPtr); 

или для итератора

int32_t x = *((int32_t*)(&(*itt))); 

, но они действительно чувствуют себя, как взломать, и хотя они могут быть обернуты в шаблонной функции, есть не более прямой способ рассказать компилятору, что я хочу?

+0

Если есть несоответствия в Endian-Несс между отправитель/протокол и ваш код, выполняющий обработку приема, есть другие соображения, кроме тех, которые вы запрашиваете. Помимо очевидного, например, некоторые протоколы определяют Endian-ness на уровне WORD, но ни один на уровне DWORD, поэтому у вас может быть ТО, с которым нужно иметь дело. – franji1

+0

Я уверен, что если вы используете intX_t, и работаете на локальном компьютере (т. Е. Отсутствуют риски несоответствия между собой), оба выражения работают и не подвержены неопределенным поведением, очевидно, прежде чем использовать это, вы должны быть уверены, что у вас есть по крайней мере, X - 1 символов после начального. Если у вас уже есть указатель на символ, используйте первый, другой, второй или: & myvector [x] или & mystring [x] как charPtr. – gabry

ответ

1

Правильный, избегая неопределенное поведение, способ сделать это будет:

int32_t x; 
memcpy(&x, charPtr, sizeof(x)); 

который можно обернуть в шаблоне функции:

template <class T, 
    std::enable_if_t<std::is_trivially_default_constructible<T>::value && 
     std::is_trivially_copyable<T>::value, int> = 0> 
T unpack(unsigned char* p) { 
    T val; 
    memcpy(&val, p, sizeof(val)); 
    return val; 
} 
+0

Это поведение определено, если он работает на локальном компьютере, ваш код добавит ненужные накладные расходы ... – gabry

+0

@gabry Он определяется только в том случае, если существует объект типа 'int32_t', который существует в' charPtr'. – Barry

+0

@gabry Также OP хочет копию ... – Barry

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

  • Нет связанных вопросов^_^