我有一个字节数组,来自网络(因此是大端),我想提取其中两个字节,传递给__builtin_bswap16()并转换为little-endian。
如果我知道它们在数组中的偏移量,我如何获得这两个字节?
答案 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),反之亦然。