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中文网其他相关文章!