从数组解析两个字节到uint16_t?

时间:2016-04-16 14:52:00

标签: c++

我有一个字节数组,来自网络(因此是大端),我想提取其中两个字节,传递给__builtin_bswap16()并转换为little-endian。

如果我知道它们在数组中的偏移量,我如何获得这两个字节?

4 个答案:

答案 0 :(得分:2)

要从uint16_t数组中提取uint8_t而不必担心对齐或别名问题,并且不重新实现系统已经提供给您的内容,请使用{{1} }。

memcpy

如果它处于网络(大端)订单中并且您想将其转换为主机订单(可能是小端,但不限于此),请使用uint16_t val; memcpy(&val, ptr, sizeof val); 作为Sam Varshavchik的回答。

ntohs

可以通过移动字节来实现它,但是如果标准库函数已经做了你想做的事情,那么我说要坚持使用标准库函数 * 至少在你有令人信服的理由不这样做之前。

*在这种情况下是POSIX标准,而不是C ++标准。

答案 1 :(得分:0)

您可能正在寻找ntohs(3)

答案 2 :(得分:0)

案例A:

 value = ((uint16_t)(array[X]) << 8) | (uint16_t)array[X + 1];

案例B:

 value = ntohs(*(unit16_t*)(char*)(array + X));

如果数组的类型已经为char,则不需要char * cast。大多数情况下,编译器无论如何都会想出来;但从技术上讲,没有它就是未定义的行为。

答案 3 :(得分:0)

我假设你的源数据是uint8_t *src = /* your source */; ,因为没有另外指定。因此:

uint16_t

您想要在给定偏移处提取一个uint8_t high = src[offset], low = src[offset + 1]; uint16_t v = high << 8 | low; /* offset and offset+1 must be in a valid range */ ;这意味着:

uint16_t v = (src[offset] << 8) | src[offset+1];

或者,更紧凑:

v

然后相应地将bswap转换为小端,但注意普通__builtin_bswapX是不够的。这是因为htonX(其中X是字节数)只是交换字节,等同于ntohX / htonX:这些也检查你的机器字节序,如果需要,继续交换;否则他们就是无操作。 实际上,如果你在BE架构上,set rowcount必须是无操作(数据已经是BE),反之亦然。