字节序转换,而不考虑字节序 [英] endianness conversion, regardless of endianness
问题描述
htonl()
或 ntohl()
的许多实现会首先测试平台的字节序,然后返回
Many implementations of htonl()
or ntohl()
test for the endianness of the platform first and then return a function which is either a no-op or a byte-swap.
我曾经在网络上阅读过有关处理大尾数转换的一些技巧的网页,无需任何有关硬件配置的先入为主的知识。仅仅考虑字节序是什么:内存中整数的表示。但是我再也找不到了,所以我这样写:
I once read a page on the web about a few tricks to handle to/from big/little-endian conversions, without any preconceived knowledge of the hardware configuration. Just taking endianness for what it is : a representation of integers in memory. But I could not find it again, so I wrote this :
typedef union {
uint8_t b[4];
uint32_t i;
} swap32_T;
uint32_t to_big_endian(uint32_t x) {
/* convert to big endian, whatever the endianness of the platform */
swap32_T y;
y.b[0] = (x & 0xFF000000) >> 24;
y.b[1] = (x & 0x00FF0000) >> 16;
y.b[2] = (x & 0x0000FF00) >> 8;
y.b[3] = (x & 0x000000FF);
return y.i;
}
我的两个问题是:
- 您知道一种更干净的方式编写此
to_big_endian()
函数的方法吗? - 您曾经为这个神秘的页面添加了书签吗?找不到,其中包含有关字节序的非常宝贵的(因为不寻常的)建议?
- Do you know a cleaner way to write this
to_big_endian()
function ? - Did you ever bookmarked this mysterious page I can not find, which contained very precious (because unusual) advices on endianness ?
并不是真正的重复项(即使非常接近)主要是因为我 not 不想检测字节序。相同的代码在两种体系结构上编译,结果相同
not really a duplicate (even if very close) mainly because I do not want to detect endianness. The same code compile on both architecture, with the same result
- 对于
u = 0x12345678
(存储为0x78 0x56 0x34 0x12
) -
to_big_endian( u)= 0x12345678
(存储为0x78 0x56 0x34 0x12
)
- for
u = 0x12345678
(stored as0x78 0x56 0x34 0x12
) to_big_endian(u) = 0x12345678
(stored as0x78 0x56 0x34 0x12
)
- 用于
u = 0x12345678
(存储为0x12 0x34 0x56 0x78
) -
to_big_endian(u)= 0x78563412
(存储为0x78 0x56 0x34 0x12
)
- for
u = 0x12345678
(stored as0x12 0x34 0x56 0x78
) to_big_endian(u) = 0x78563412
(stored as0x78 0x56 0x34 0x12
)
相同的代码,相同的结果...在内存中。
same code, same result... in memory.
推荐答案
这是我自己的版本(尽管本例中的内存约定是小端而不是大端):
Here is my own version of the same (although memory convention in this example is little endian instead of big endian) :
/* unoptimized version; solves endianess & alignment issues */
static U32 readLE32 (const BYTE* srcPtr)
{
U32 value32 = srcPtr[0];
value32 += (srcPtr[1]<<8);
value32 += (srcPtr[2]<<16);
value32 += (srcPtr[3]<<24);
return value32;
}
static void writeLE32 (BYTE* dstPtr, U32 value32)
{
dstPtr[0] = (BYTE)value32;
dstPtr[1] = (BYTE)(value32 >> 8);
dstPtr[2] = (BYTE)(value32 >> 16);
dstPtr[3] = (BYTE)(value32 >> 24);
}
基本上,函数原型中缺少什么以使代码更容易理解读取是指向源或目标内存的指针。
Basically, what's missing in your function prototype to make the code a bit easier to read is a pointer to the source or destination memory.
这篇关于字节序转换,而不考虑字节序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!