我有一个std::string
,包含从串口接收的四个字节。这些字节代表小端的两个int16_t
。由于该软件仅在x86上运行,因此无需更改字节序。
我获得单个整数值的第一种方法是:
std::string inData = ...; // inData.length() = 4
int16_t measurement[2];
measurement[0] = ( (int16_t)inData[0] << 8 ) | (int16_t)inData[1];
measurement[1] = ( (int16_t)inData[2] << 8 ) | (int16_t)inData[3];
好吧,结果看起来像未定义的行为。我希望从inData[x]
到int16_t
的转换会使四个MSB设置为零,但这似乎不是真的。所以我尝试了这个:
const uint8_t *castedData = reinterpret_cast<const uint8_t*>(&inData[0]);
measurement[0] = ( (int16_t)castedData[0] << 8 ) | (int16_t)castedData[1];
measurement[1] = ( (int16_t)castedData[2] << 8 ) | (int16_t)castedData[3];
它按预期工作。但是,这是“正确的”方式吗?或者有没有办法实现这一点而不使用reinterpret_cast
?
我看了Converting unsigned chars to signed integer,但是接受的答案和有关别名的评论使我感到困惑。
答案 0 :(得分:1)
两者都是正确的,后者在调用c_str()
并投射结果指针时会更好。前者的问题是std :: string很可能基于signed char
。因此,转换为较大的int
类型会扩展符号位,例如0x80
将变为0xff80
。
如果您使用以下内容修复原件:
( (uint8_t)inData[0] << 8 ) | (uint8_t)inData[1];
它也会起作用......