首页 > 后端开发 > C++ > 在 C 中将 64 位整数转换为网络字节顺序时如何实现可移植性?

在 C 中将 64 位整数转换为网络字节顺序时如何实现可移植性?

Susan Sarandon
发布: 2024-10-30 04:37:28
原创
936 人浏览过

How to Achieve Portability When Converting 64-Bit Integers to Network Byte Order in C  ?

C 中 64 位整数的网络字节顺序转换的可移植性问题

在 C 中,需要转换 64 位整数特定应用程序的“网络字节顺序”,例如实现内存缓存协议。尽管存在用于转换 32 位整数的 htonl() 函数,但用于转换 32 位整数的类似函数 (htonll()) 仍然难以捉摸。

标准函数注意事项

不幸的是,目前 C 语言中没有可移植的标准函数可以执行 64 位网络字节顺序转换。这种缺失产生了对自定义实现的需求。

自定义实现

要实现 htonll(),我们必须首先确定系统的字节顺序。一种可靠的方法是在运行时计算已知字节顺序(例如 42)的整数变量的值:

<code class="cpp">static const int num = 42;
bool isBigEndian = (*reinterpret_cast<const char *>(&num) == num);</code>
登录后复制

接下来,我们可以根据字节顺序执行转换:

<code class="cpp">uint64_t htonll(uint64_t value)
{
    if (isBigEndian)
    {
        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;
    }
}
登录后复制

用于可移植性的宏

或者,宏可以提供一种简洁的方式来定义 htonll() 及其对应项 ntohll():

<code class="cpp">#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))</code>
登录后复制

这些宏依赖系统固有的字节排序行为来确定必要的字节交换。

编译器特定的宏

一些编译器和操作系统提供特定的宏来确定字节顺序。例如,在支持它的系统上,我们可以使用:

<code class="cpp">#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</code>
登录后复制

通过采用这些技术,htonll() 和 ntohll() 的自定义实现可以跨各种系统和编译器移植。

以上是在 C 中将 64 位整数转换为网络字节顺序时如何实现可移植性?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板