简体   繁体   English

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

[英]Endianness manipulation - is there a C library for this?

With the sort of programs I write (working with raw file data) I often need functions to convert between big and little endian. 有了我编写的程序(使用原始文件数据),我经常需要在大端和小端之间进行转换的函数。 Usually I write these myself (which is covered by many other posts here) but I'm not that keen on doing this for a number of reasons - the main one being lack of testing. 通常我自己写这些(这里有许多其他帖子都介绍过),但我并不是因为多种原因而热衷于这样做 - 主要原因是缺乏测试。 I don't really want to spend ages testing my code in a big endian emulator, and often just omit the code for big endian machines altogether. 我真的不想花大量时间在大端模拟器中测试我的代码,而且通常只是省略大端机器的代码。 I also would rather make use of faster functions provided by various compilers, while still keeping my programs cross-platform. 我还希望利用各种编译器提供的更快的功能,同时仍然保持我的程序跨平台。

The only things I can find are socket calls like htons() but they require different #include files on each platform, and some GPL code like this , however that particular file, while comprehensive, seems to miss out on some of the high performance functions provided by some compilers. 我能找到的唯一的东西是套接字调用,比如htons(),但它们在每个平台上都需要不同的#include文件,还有一些像这样的 GPL代码,但是这个特定的文件虽然全面,但似乎错过了一些高性能函数由一些编译器提供。

So, does anyone know of a library (ideally just a .h file) that is well tested and provides a standard set of functions for dealing with endianness across many compilers and platforms? 那么,有没有人知道一个经过充分测试的库(理想情况下只是一个.h文件)并提供了一套标准的函数来处理许多编译器和平台的字节序?

There have been a number of proposals for a Boost class (for C++, at least) to do exactly that over the last decade, but none have ever come to fruition, unfortunately. 在过去的十年中,有一些关于Boost类(至少是C ++)的建议就是这样做的,但遗憾的是没有一个提出过。

I'm not aware of any better generalized solution than the htons() function set. 我不知道比htons()函数集更好的通用解决方案。

It's easiest just to not write endian-dependent code. 最简单的方法是不编写依赖于字节序的代码。 You never should care exactly what the endianness is of the system you're running on; 你永远不应该完全关心你正在运行的系统的字节顺序; the only thing that should matter is what the mandated endianness is for any external data you're reading or writing. 唯一重要的是你要读取或写入的任何外部数据的强制性字节顺序。 You shouldn't be asking about conversions between big- and little-endian values, but rather about conversions from a specific endianness to the host endianness, and you can write that code in an endian-agnostic way that's (almost) completely portable: 您不应该询问大端和小端值之间的转换,而是要讨论从特定字节序到主机字节序的转换,并且您可以以(几乎)完全可移植的方式编写该代码:

For example: suppose you're reading a 32-bit big-endian integer from a file stream: 例如:假设您正在从文件流中读取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;
}

(I say "(almost) completely portable" because it does assume that there are 8 bits per byte. But if you're on a system where that isn't true, you're probably going to have bigger issues when dealing with external data.) (我说“(几乎)完全可移植”,因为它确实假设每个字节有8位。但是如果你的系统不是真的,那么在处理外部时你可能会遇到更大的问题数据。)

On linux, there's <endian.h> 在linux上,有<endian.h>

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

I'd be interested to learn if other operating systems support it as well. 我有兴趣了解其他操作系统是否也支持它。

For what its worth... 物有所值...

Like the OP, I often need byte-ordering aware routines for shuffling data among different machines and protocols. 与OP一样,我经常需要字节顺序感知例程来在不同的机器和协议之间混洗数据。 (In my case, I need them for embedded processors rather than for big iron.) (就我而言,我需要它们用于嵌入式处理器而不是大铁。)

After several iterations, I've posted an endian library written in pure C to Github. 经过几次迭代,我发布了一个用纯C编写的字节库到Github。 What it lacks in documentation it makes up for in comprehensive unit testing. 它在综合单元测试中弥补的文档中缺少什么。

https://github.com/rdpoor/endian https://github.com/rdpoor/endian

endian 's main departure from most byte-ordering libraries is that it doesn't presume a byte-at-a-time read or write function, but rather works directly on void * memory buffers. endian与大多数字节排序库的主要不同之处在于它不会假定一次一个字节的读或写函数,而是直接在void *内存缓冲区上工作。 This gives the compiler the freedom to optimize what it can, and in the case that the desired byte-ordering matches the host machine, it short-circuits byte shuffling altogether. 这使编译器可以自由地优化它,并且在所需的字节排序与主机匹配的情况下,它完全短路字节混洗。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM