字节序操作 - 有一个C库吗?

时间:2010-04-03 10:20:15

标签: c endianness

对于我编写的那些程序(使用原始文件数据),我经常需要在大端和小端之间进行转换的函数。通常我自己写这些(这里有许多其他帖子都介绍过),但我并不是因为多种原因而热衷于这样做 - 主要原因是缺乏测试。我真的不想花大量时间在大端模拟器中测试我的代码,而且通常只是省略大端机器的代码。我还希望利用各种编译器提供的更快的功能,同时仍然保持我的程序跨平台。

我能找到的唯一的东西是套接字调用,比如htons(),但是它们需要在每个平台上使用不同的#include文件,以及一些GPL代码like this,但是这个特定的文件虽然全面,但似乎错过了某些编译器提供的一些高性能函数。

那么,有没有人知道一个经过充分测试的库(理想情况下只是一个.h文件)并提供了一套标准函数来处理许多编译器和平台的字节序?

4 个答案:

答案 0 :(得分:2)

在过去的十年中,有很多关于Boost类(至少是C ++)的建议就是这样做的,但遗憾的是没有一个提出过。

我不知道比htons()函数集更好的通用解决方案。

答案 1 :(得分:2)

最简单的方法是不编写依赖于字节序的代码。你永远不应该完全关心你正在运行的系统的字节顺序;唯一重要的是你要读取或写入的任何外部数据的强制性字节顺序。您不应该询问大端和小端值之间的转换,而应该讨论从特定字节序到主机字节序的转换,并且您可以以一种(几乎)完全可移植的方式编写该代码:< / p>

例如:假设您正在从文件流中读取32位大端整数:

/*
 * Note that callers should check feof(fp) afterward to verify that
 * there was enough data to read.
 */
uint32_t GetBE32(FILE* fp)
{
    uint32_t result;
    result  = fgetc(fp) << 24;
    result |= fgetc(fp) << 16;
    result |= fgetc(fp) <<  8;
    result |= fgetc(fp);
    return result;
}

uint32_t GetLE32(FILE* fp)
{
    uint32_t result;
    result  = fgetc(fp);
    result |= fgetc(fp) <<  8;
    result |= fgetc(fp) << 16;
    result |= fgetc(fp) << 24;
    return result;
}

(我说“(几乎)完全可移植”,因为它确实假设每个字节有8位。但如果你的系统不是这样,你可能会遇到更大的问题处理外部数据。)

答案 2 :(得分:1)

在linux上,有<endian.h>

http://man7.org/linux/man-pages/man3/htole32.3.html

我有兴趣了解其他操作系统是否也支持它。

答案 3 :(得分:1)

它的价值......

与OP一样,我经常需要字节顺序感知例程来在不同的机器和协议之间混洗数据。 (在我的情况下,我需要它们用于嵌入式处理器而不是大铁。)

经过几次迭代后,我发布了一封用纯C写的endian library给Github。它在综合单元测试中弥补的文档中缺少什么。

https://github.com/rdpoor/endian

endian与大多数字节排序库的主要不同之处在于,它不会假定一次一个字节的读或写函数,而是直接在{{{ 1}}内存缓冲区。这使编译器可以自由地优化它,并且在所需的字节顺序与主机匹配的情况下,它会完全短路字节混洗。