2017-01-23 117 views
1

我經常遇到這樣的情況,即通過協議接收打包的二進制數據(即變量未正確對齊的地方),數據通常以std :: string,std :: vector或其他方式出現這樣的容器。什麼是從二進制緩衝區初始化變量的正確方法?

我的問題是解壓這些數據的最佳做法是什麼?我通常將執行類似:

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

或迭代器

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

但這些真的感覺像一個黑客,雖然他們可以在一個模板函數包裹起來,是不是有一個更直接告訴編譯器我想要什麼?

+0

如果有之間的字節序不一致發件人/協議和您的代碼進行接收處理,除了您要求的以外,還有其他一些考慮因素。除了顯而易見的,例如一些協議在WORD級別定義了Endian - ness,但是在DWORD級別沒有,所以你可能有這個處理。 – franji1

+0

我很確定,如果你使用intX_t並且你正在使用本地機器(即沒有endian不匹配風險),那麼這兩個表達式都可以工作,並且不會產生未定義的行爲,顯然在使用之前,你應該確保你有在初始之後至少有X - 1個字符。如果您已經有char指針,則使用第一個字符指針,或者使用第二個字符指針或: &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只有在存在'charPtr'處存在類型爲'int32_t'的對象時才定義。 – Barry

+0

@gabry另外OP想要一個副本... – Barry

相關問題