我想处理由外部库提供的数据。
lib保存数据并提供对它的访问,如下所示:
const uint8_t* data;
std::pair<const uint8_t*, const uint8_t*> getvalue() const {
return std::make_pair(data + offset, data + length);
}
我知道当前数据包含两个uint16_t
数字,但是我需要更改其字节序。因此,数据总共为4个字节长,并包含以下数字:
66 4 0 0
所以我想分别用uint16_t
和1090
值得到两个0
数字。
我可以进行基本算术并在一处更改字节序:
pair<const uint8_t*, const uint8_t*> dataPtrs = library.value();
vector<uint8_t> data(dataPtrs.first, dataPtrs.second);
uint16_t first = data[1] <<8 + data[0]
uint16_t second = data[3]<<8 + data[2]
但是我想做些更优雅的事情(如果有更好的方法获得uint16_t
,则向量是可替换的。
如何更好地从uint16_t
创建uint8_t*
?如果可能的话,我会避免使用memcpy,而应使用更现代/安全的方法。
Boost具有一些不错的仅标头的字节序library,它可以工作,但是需要uint16_t
输入。
为了更进一步,Boost还提供了用于更改字节序的数据类型,因此我可以创建一个结构:
struct datatype {
big_int16_buf_t data1;
big_int16_buf_t data2;
}
是否可以安全地(填充,平台相关性等)将有效的4字节长的uint8_t*
强制转换为datatype
?也许有这样的工会?
typedef union {
uint8_t u8[4];
datatype correct_data;
} mydata;
也许有这样的结合?
没有在C ++中,对带有联合的类型修剪没有很好的定义。
这将起作用:
datatype d{};
std::memcpy(&d, data, sizeof d);
请注意,这将导致不同的值,具体取决于CPU的本地字节顺序。对于便携性而言,这不是理想的选择。
uint16_t first = data[1] <<8 + data[0] uint16_t second = data[3]<<8 + data[2]
但是我想做些更优雅的事情
实际上(主观上,我认为)这是最优雅的方式,因为它在所有系统上都以相同的方式工作。这会将数据读取为小端,无论CPU是小端,大端还是其他端。这是便携式的。
但是我想做些更优雅的事情(如果有更好的方法来获取uint16_ts,向量是可替换的。
矢量似乎完全没有意义。您也可以使用:
const std::uint8_t* data = dataPtrs.first;