C++ 没有ntohs的字节序交换
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10341477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Endianness swap without ntohs
提问by xdumaine
I am writing an ELF analyzer, but I'm having some trouble converting endianness properly. I have functions to determine the endianness of the analyzer and the endiannness of the object file.
我正在编写一个 ELF 分析器,但是我在正确转换字节序时遇到了一些麻烦。我有函数来确定分析器的字节序和目标文件的字节序。
Basically, there are four possible scenarios:
基本上,有四种可能的情况:
- A big endian compiled analyzer run on a big endian object file
- nothing needs converted
- A big endian compiled analyzer run on a little endian object file
- the byte order needs swapped, but ntohs/l() and htons/l() are both null macros on a big endian machine, so they won't swap the byte order. This is the problem
- A little endian compiled analyzer run on a big endian object file
- the byte order needs swapped, so use htons() to swap the byte order
- A little endian compiled analyzer run on a little endian object file.
- nothing needs converted
- 大端编译分析器在大端目标文件上运行
- 什么都不需要转换
- 大端编译分析器在小端目标文件上运行
- 字节顺序需要交换,但 ntohs/l() 和 htons/l() 在大端机器上都是空宏,因此它们不会交换字节顺序。这就是问题
- 小端编译分析器在大端目标文件上运行
- 字节顺序需要交换,所以使用 htons() 来交换字节顺序
- 小端编译分析器在小端目标文件上运行。
- 什么都不需要转换
Is there a function I can use to explicitly swap byte order/change endianness, since ntohs/l() and htons/l() take the host's endianness into account and sometimes don't convert? Or do I need to find/write my own swap byte order function?
是否有一个函数可以用来显式交换字节顺序/更改字节序,因为 ntohs/l() 和 htons/l() 考虑了主机的字节序并且有时不转换?或者我需要找到/编写我自己的交换字节顺序函数吗?
采纳答案by David Heffernan
Do I need to find/write my own swap byte order function?
我需要找到/编写我自己的交换字节顺序函数吗?
Yes you do. But, to make it easy, I refer you to this question: How do I convert between big-endian and little-endian values in C++?which gives a list of compiler specific byte order swap functions, as well as some implementations of byte order swap functions.
是的你是。但是,为了方便起见,我建议您参考这个问题:如何在 C++ 中的大端和小端值之间进行转换?它给出了特定于编译器的字节顺序交换函数的列表,以及字节顺序交换函数的一些实现。
回答by Matthieu M.
I think it's worth raising The Byte Order Fallacyarticle here, by Rob Pyke (one of Go's author).
我认为值得在这里提出由 Rob Pyke(Go 的作者之一)撰写的The Byte Order Fallacy文章。
If you do things right -- ie you do not assumeanything about your platforms byte order -- then it will just work. All you need to care about is whether ELF format files are in Little Endianor Big Endianmode.
如果你做对了——即你不对平台字节顺序做任何假设——那么它就会起作用。您只需要关心 ELF 格式的文件是处于Little Endian模式还是Big Endian模式。
From the article:
从文章:
Let's say your data stream has a little-endian-encoded 32-bit integer. Here's how to extract it (assuming unsigned bytes):
假设您的数据流有一个小端编码的 32 位整数。以下是提取它的方法(假设是无符号字节):
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
If it's big-endian, here's how to extract it:
如果是 big-endian,这里是提取它的方法:
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
And just let the compiler worry about optimizing the heck out of it.
让编译器担心优化它。
回答by Rafa? Rawicki
In Linux there are several conversion functionsin endian.h
, which allow to convert between arbitrary endianness:
在Linux中有几个转换函数中endian.h
,允许任意字节序之间的转换:
uint16_t htobe16(uint16_t host_16bits);
uint16_t htole16(uint16_t host_16bits);
uint16_t be16toh(uint16_t big_endian_16bits);
uint16_t le16toh(uint16_t little_endian_16bits);
uint32_t htobe32(uint32_t host_32bits);
uint32_t htole32(uint32_t host_32bits);
uint32_t be32toh(uint32_t big_endian_32bits);
uint32_t le32toh(uint32_t little_endian_32bits);
uint64_t htobe64(uint64_t host_64bits);
uint64_t htole64(uint64_t host_64bits);
uint64_t be64toh(uint64_t big_endian_64bits);
uint64_t le64toh(uint64_t little_endian_64bits);
Edited, less reliable solution. You can use union to access the bytes in any order. It's quite convenient:
编辑,不太可靠的解决方案。您可以使用 union 以任何顺序访问字节。还是挺方便的:
union {
short number;
char bytes[sizeof(number)];
};
回答by bames53
The ntoh functions can swap between more than just big and little endian. Some systems are also 'middle endian' where the bytes are scrambled up rather than just ordered one way or another.
ntoh 函数不仅可以在大端和小端之间进行交换。一些系统也是“中间端”,其中字节被加扰而不是仅以一种或另一种方式排序。
Anyway, if all you care about are big and little endian, then all you need to know is if the host and the object file's endianess differ. You'll have your own function which unconditionally swaps byte order and you'll call it or not based on whether or not host_endianess()==objectfile_endianess()
.
无论如何,如果您只关心大端和小端,那么您只需要知道主机和目标文件的端序是否不同。您将拥有自己的无条件交换字节顺序的函数,您将根据是否调用它host_endianess()==objectfile_endianess()
。
回答by Mohammed Safwat
If I would think about a cross-platform solution that would work on windows or linux, I would write something like:
如果我考虑一个可以在 windows 或 linux 上运行的跨平台解决方案,我会写如下:
#include <algorithm>
// dataSize is the number of bytes to convert.
char le[dataSize];// little-endian
char be[dataSize];// big-endian
// Fill contents in le here...
std::reverse_copy(le, le + dataSize, be);