ere*_*eOn 60 c++ 64-bit portability endianness htonl
我正在研究memcache协议的实现,在某些点上,它使用64位整数值.这些值必须以"网络字节顺序"存储.
我希望有一些uint64_t htonll(uint64_t value)
功能可以进行更改,但不幸的是,如果它存在,我找不到它.
所以我有1或2个问题:
我想到了一个基本的实现,但我不知道如何在编译时检查字节序以使代码可移植.所以你的帮助非常受欢迎;)
谢谢.
这是我写的最终解决方案,感谢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;
}
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*ndy 16
你可能正在寻找bswap_64
我认为它几乎被支持,但我不会称之为标准.
您可以通过创建值为1的int,将int的地址转换为a char*
并检查第一个字节的值来轻松检查字节序.
例如:
int num = 42;
if(*(char *)&num == 42)
{
//Little Endian
}
else
{
//Big Endian
}
Run Code Online (Sandbox Code Playgroud)
知道了这一点,你也可以做一个简单的交换功能.
您也可以始终使用包含可移植跨平台的endian宏的boost.
del*_*106 15
#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))
Run Code Online (Sandbox Code Playgroud)
测试(1 == htonl(1))简单地确定(在运行时遗憾地)硬件架构是否需要字节交换.没有任何可移植的方法可以在编译时确定架构是什么,所以我们使用"htonl",这在这种情况下是可移植的.如果需要进行字节交换,那么我们使用htonl一次交换32位(记住也要交换两个32位字).
您可以尝试使用uint64_t htobe64(uint64_t host_64bits)
&
uint64_t be64toh(uint64_t big_endian_64bits)
,反之亦然。
这似乎适用于 C;我做错了什么吗?
uint64_t htonll(uint64_t value) {
int num = 42;
if (*(char *)&num == 42) {
uint32_t high_part = htonl((uint32_t)(value >> 32));
uint32_t low_part = htonl((uint32_t)(value & 0xFFFFFFFFLL));
return (((uint64_t)low_part) << 32) | high_part;
} else {
return value;
}
}
Run Code Online (Sandbox Code Playgroud)