我的工作在一个执行缓存协议,该协议,在某一点,使用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;
}

警告:未经测试的代码!请测试之前使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top