是否有任何"标准"htonl状的函数为64位整数在C++?
-
26-09-2019 - |
题
我的工作在一个执行缓存协议,该协议,在某一点,使用64位整数值。这些价值观必须存在"网络字节秩序"。
我希望能有一些 uint64_t htonll(uint64_t value)
能做的改变,但不幸的是,如果它存在,我找不到它。
所以我有1或2个问题:
- 是否有任何 便携式 (Windows、Linux、AIX)标准的功能做到这一点?
- 如果没有这种功能,你将如何实现它吗?
我心里有一个基本实现,但我不知道如何检查的字节序在编制时使代码的便携性。所以你的帮助比在这里欢迎;)
谢谢你。
这里是最后的解决方案我写的,谢谢布莱恩的解决方案。
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;
}
}
解决方案
你可能是在寻找 bswap_64
我认为这是支持几乎无处不在,但我不会叫它标准。
你可以轻易地检查字节序通过创建一个int值为1,铸造你int的地址作为一个 char*
和检查的价值,第一个字节。
例如:
int num = 42;
if(*(char *)&num == 42)
{
//Little Endian
}
else
{
//Big Endian
}
知道这个你也可以做一个简单的功能,没有交换。
你也可以永远使用其中包含endian宏其是便携式的跨平台。
其他提示
#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))简单地确定(在运行时,可悲的是)如果硬件结构requres字节交换。没有任何便携式方法来确定在编制时什么样的架构,因此,我们求助于使用"htonl",这是作为便携式,因为它得到在这种情况。如果字节交换是必需的,然后我们交换的32位的时间使用htonl(记住,以交换两个32位字)。
这里是另一种方式来执行交换,是便携式的,大多数编译器和操作系统,包括AIX,BSDs,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__
和朋友。
你可以试试 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;
}
}
减少开销的"如果num==..." 使用预处理器定义:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#else
#endif
编辑:两者结合(用布莱恩的代码):
uint64_t htonll(uint64_t value)
{
int num = 42;
if(*(char *)&num == 42)
return (htonl(value & 0xFFFFFFFF) << 32LL) | htonl(value >> 32);
else
return value;
}
警告:未经测试的代码!请测试之前使用。