我正在开发memcache协议的一个实现,在某些情况下,它使用64位整数值。这些值必须以“网络字节顺序”存储。
我希望有一些uint64_t htonll(uint64_t value)
函数来做更改,但不幸的是,如果它存在,我找不到它。
所以我有一两个问题:
我有一个基本的实现,但我不知道如何在编译时检查字节顺序以使代码可移植。因此,我们非常欢迎您的帮助;)
谢谢。
这是我写的最终解决方案,感谢Brian的解决方案。
uint64_t htonll(uint64_t value)
{
// The answer is 42
static const int num = 42;
// Check the endianness
if (*reinterpret_cast<const char*>(&num) == num)
{
const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));
return (static_cast<uint64_t>(low_part) << 32) | high_part;
} else
{
return value;
}
}
发布于 2010-06-11 20:14:10
您可能正在寻找bswap_64
,我认为几乎所有地方都支持它,但我不会将其称为标准。
通过创建一个值为1的int,将int的地址转换为char*
并检查第一个字节的值,可以很容易地检查字节顺序。
例如:
int num = 42;
if(*(char *)&num == 42)
{
//Little Endian
}
else
{
//Big Endian
}
了解了这一点,您还可以创建一个执行交换的简单函数。
您也可以始终使用boost,它包含可移植的跨平台的endian宏。
发布于 2015-02-19 03:28:05
#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
测试(1==htonl(1))只是确定(不幸的是)硬件架构是否需要字节交换。没有任何可移植的方法来在编译时确定体系结构是什么,所以我们求助于使用"htonl",它在这种情况下是可移植的。如果需要字节交换,那么我们使用htonl一次交换32位(记住也交换两个32位字)。
这里有另一种执行交换的方法,它可以在大多数编译器和操作系统之间移植,包括AIX、BSD、Linux和Solaris。
#if __BIG_ENDIAN__
# define htonll(x) (x)
# define ntohll(x) (x)
#else
# define htonll(x) ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
# define ntohll(x) ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
#endif
重要的部分是使用__BIG_ENDIAN__
或__LITTLE_ENDIAN__
,而不是__BYTE_ORDER__
、__ORDER_BIG_ENDIAN__
或__ORDER_LITTLE_ENDIAN__
。一些编译器和操作系统缺少__BYTE_ORDER__
和朋友。
发布于 2017-10-23 02:06:59
您可以尝试使用uint64_t htobe64(uint64_t host_64bits)
和uint64_t be64toh(uint64_t big_endian_64bits)
,反之亦然。
https://stackoverflow.com/questions/3022552
复制相似问题