首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于C++中的64位整数,有没有类似htonl的“标准”函数?

对于C++中的64位整数,有没有类似htonl的“标准”函数?
EN

Stack Overflow用户
提问于 2010-06-11 20:09:56
回答 7查看 47K关注 0票数 73

我正在开发memcache协议的一个实现,在某些情况下,它使用64位整数值。这些值必须以“网络字节顺序”存储。

我希望有一些uint64_t htonll(uint64_t value)函数来做更改,但不幸的是,如果它存在,我找不到它。

所以我有一两个问题:

  • 有没有便携 (Windows、Linux、AIX)的标准函数可以做到这一点?
  • 如果没有这样的函数,您将如何实现它?

我有一个基本的实现,但我不知道如何在编译时检查字节顺序以使代码可移植。因此,我们非常欢迎您的帮助;)

谢谢。

这是我写的最终解决方案,感谢Brian的解决方案。

代码语言:javascript
运行
复制
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;
    }
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-06-11 20:14:10

您可能正在寻找bswap_64,我认为几乎所有地方都支持它,但我不会将其称为标准。

通过创建一个值为1的int,将int的地址转换为char*并检查第一个字节的值,可以很容易地检查字节顺序。

例如:

代码语言:javascript
运行
复制
int num = 42;
if(*(char *)&num == 42)
{
   //Little Endian
}
else
{
   //Big Endian
} 

了解了这一点,您还可以创建一个执行交换的简单函数。

您也可以始终使用boost,它包含可移植的跨平台的endian宏。

票数 19
EN

Stack Overflow用户

发布于 2015-02-19 03:28:05

代码语言:javascript
运行
复制
#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。

代码语言:javascript
运行
复制
#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__和朋友。

票数 22
EN

Stack Overflow用户

发布于 2017-10-23 02:06:59

您可以尝试使用uint64_t htobe64(uint64_t host_64bits)uint64_t be64toh(uint64_t big_endian_64bits),反之亦然。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3022552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档