C ++中是否有64位整数的“标准”htonl函数?
我正在研究memcache协议的实现,在某些情况下,它使用64位整数值。 这些值必须以“networking字节顺序”存储。
我希望有一些uint64_t htonll(uint64_t value)
函数来进行更改,但不幸的是,如果存在,我找不到它。
所以我有1或2个问题:
- 有没有任何便携式 (Windows,Linux,AIX)标准function来做到这一点?
- 如果没有这样的function,你会怎么实现呢?
我想到了一个基本的实现,但我不知道如何在编译时检查字节序以使代码可移植。 所以你的帮助是在这里比欢迎;)
谢谢。
这是我写的最后的解决scheme,感谢Brian的解决scheme。
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
我认为它几乎在任何地方都受到支持,但是我不会称之为标准。
您可以通过创build一个值为1的int来轻松检查字节序,将您的int地址转换为char*
并检查第一个字节的值。
例如:
int num = 42; if(*(char *)&num == 42) { //Little Endian } else { //Big Endian }
知道这一点,你也可以做一个简单的function,交换。
你也可以总是使用包含可移植跨平台的endianmacros的boost。
#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))
testing(1 == htonl(1))只是简单地确定(在运行时),硬件架构是否需要字节交换。 在编译时没有任何可移植的方法来确定这个架构是什么,所以我们使用“htonl”,它就像在这种情况下一样便携。 如果需要字节交换,那么我们一次使用htonl交换32位(还记得交换两个32位字)。
这似乎在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; } }
为了减less“if num == …”的开销,使用预处理器定义:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #else #endif
uint64_t htobe64(uint64_t host_64bits)
您可以尝试使用uint64_t htobe64(uint64_t host_64bits)
和uint64_t be64toh(uint64_t big_endian_64bits)
。
编辑:结合两个(使用布赖恩的代码):
uint64_t htonll(uint64_t value) { int num = 42; if(*(char *)&num == 42) return (htonl(value & 0xFFFFFFFF) << 32LL) | htonl(value >> 32); else return value; }
警告:未经testing的代码! 使用前请先testing一下。