我们为x86和x64平台开发了win32应用程序。我们想在ARM平台上使用相同的应用程序。对于ARM平台,字节顺序会有所不同,即ARM平台通常使用Big endian格式。因此,我们希望在我们的设备应用程序中处理此问题。
例如//在x86 / x64中,int nIntVal = 0x12345678
在ARM中,int nIntVal = 0x78563412
如何为ARM中的以下数据类型存储值?
请澄清一下。
此致 Raphel
答案 0 :(得分:5)
Endianess仅适用于注册表< - >记忆操作。
在注册表中没有任何结尾。如果你把
int nIntVal = 0x12345678
在您的代码中,它将对任何endianess机器产生相同的效果。
所有IEEE格式(float
,double
)在所有体系结构中都是相同的,所以这并不重要。
在两种情况下你只需要关心结束:
a)您将整数写入必须在两种体系结构之间转换的文件。
解决方案:使用hton*, ntoh*
系列转换器,使用非二进制文件格式(例如XML)或标准化文件格式(例如SQLite)。
b)你转换整数指针。
int a = 0x1875824715;
char b = a;
char c = *(char *)&a;
if (b == c) {
// You are working on Little endian
}
顺便说一句,后一种代码是一种在运行时测试你的endianess的便捷方法。
数组等等如果你使用write, fwrite
调用来传递它们,你将没有任何问题,除非它们包含整数:然后看看上面。
int64_t
:看看上面。只关心你是否必须将二进制文件存储在文件或转换指针中。
答案 1 :(得分:0)
(Sergey L.,上面说,但是你大部分时间都不需要关心字节顺序。他是对的,至少有一个例外:我假设你想要将二进制数据从一个平台转换到另一个平台......)
http://en.wikipedia.org/wiki/Endianness有一个很好的概述。
简而言之:
存储数组元素的顺序不受影响(当然是数组元素中的字节顺序)
所以
关于浮点格式,请考虑http://en.wikipedia.org/wiki/Endianness#Floating-point_and_endianness。通常,它似乎遵循与整数格式相同的字节序规则,但旧的ARM平台也有例外。 (我没有第一手经验)。
一般来说,我建议先用受控实验测试原始类型的转换。
还要考虑,编译器可能在结构中使用不同的填充(这个主题尚未解决)。
希望这有帮助。
答案 2 :(得分:0)
在98%的情况下,您不需要关心字节序。除非你需要在不同endiannness的系统之间传输一些数据,或者读/写一些endian敏感文件格式,否则你不应该为此烦恼。即使在这些情况下,您也可以编写代码,以便在任何字节序下编译时正常运行。
来自Rob Pike的"The byte order fallacy"帖子:
假设您的数据流具有小端编码的32位整数。 以下是如何提取它(假设无符号字节):
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
如果它是big-endian,这是如何提取它:
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
这两个片段都适用于任何机器,独立的机器 字节顺序,独立于对齐问题,独立于 任何东西。它们是完全可移植的,给定无符号字节和32位 整数。
答案 3 :(得分:0)
arm是小端,它有两个大端变体,具体取决于体系结构,但最好只运行本机小端,其中的工具和代码量在小端模式下进行了更全面的测试。
如果您进行系统工程,那么Endianness只是系统工程中的一个因素,它可以解决所有问题,无需担心,无后顾之忧。为该设计定义接口和代码。假设例如一个处理器字节序自动导致必须使用byteswap是一个不好的假设并且最终会咬你。您最终必须交换偶数次以撤消导致交换的其他错误假设(理想情况下当然交换零次而不是2或4或6次等)。如果您在编写代码时有任何endian问题,则应将其编写为endian independent。
由于某些ARM具有BE32(字不变)和较新的臂BE8(字节不变),您将不得不做更多的工作来尝试制作通用的东西,同时试图补偿小的英特尔,小臂,BE32臂和BE8手臂。 Xscale倾向于本地运行大端,但可以作为小端运行以减少头痛。您可能认为因为ARM克隆是大端,所以都是大端,另一个不好的假设。