什么是从二进制缓冲区初始化变量的正确方法?
问题描述:
我经常遇到这样的情况,即通过协议接收打包的二进制数据(即变量未正确对齐的地方),数据通常以std :: string,std :: vector或其他方式出现这样的容器。什么是从二进制缓冲区初始化变量的正确方法?
我的问题是解压这些数据的最佳做法是什么?我通常将执行类似:
int32_t x = *((int32_t*)charPtr);
或迭代器
int32_t x = *((int32_t*)(&(*itt)));
但这些真的感觉像一个黑客,虽然他们可以在一个模板函数包裹起来,是不是有一个更直接告诉编译器我想要什么?
答
正确,避免不确定的行为,这样做的方法是:
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;
}
如果有之间的字节序不一致发件人/协议和您的代码进行接收处理,除了您要求的以外,还有其他一些考虑因素。除了显而易见的,例如一些协议在WORD级别定义了Endian - ness,但是在DWORD级别没有,所以你可能有这个处理。 – franji1
我很确定,如果你使用intX_t并且你正在使用本地机器(即没有endian不匹配风险),那么这两个表达式都可以工作,并且不会产生未定义的行为,显然在使用之前,你应该确保你有在初始之后至少有X - 1个字符。如果您已经有char指针,则使用第一个字符指针,或者使用第二个字符指针或: &myvector [x]或&mystring [x]作为charPtr。 – gabry