Android NDK的字节序

我正在使用我的新应用程序,该应用程序处理了手机摄像头捕获的图像。 我的手机是Nexus S 2.3.4。

我使用捕获的数据创建一个ARGB_8888位图。 我知道ndk映像库,但仅支持2.2及更高版本。 因此,我将Bitmap的int []传递给NDK,发现颜色字节顺序为little-endian。

我搜索了Wiki,发现手臂架构是bi-endian。[http://zh.wikipedia.org/wiki/Endianness#Bi-endian_hardware]

我的问题是,如果arm是bi-endian,如何判断特定设备中的字节顺序? 我应该在访问数据之前每次测试字节顺序吗?

7个解决方案

42 votes

直接从我的Nexus S:

> import java.nio.*;
> System.out.println(ByteOrder.nativeOrder());
LITTLE_ENDIAN

还应该有一些方法可以在NDK中获得订购。

lxgr answered 2019-11-18T00:52:18Z

37 votes

是的,大多数cpus双端配置,但是当今使用的大多数最终用户操作系统都选择在Little-endian中使用cpus。 沿着这些思路,ARM既可以方便地工作,又可以在ARM 3之后的实际默认值是little-endianess,这是它启动时采用的字节序模式。我认为可以肯定地认为所有Android设备都是little-endian,否则会这样。 如果不同的android设备混杂在一起,则需要额外的工作。

由于网络字节顺序为高位字节序,因此将计划用于数据交换的任何格式转换为网络字节顺序会很有帮助。 同样,尽管如此,但Intel,Windows,iOS和Android上的Mac OS X都是低端字节序的,因此您可能只是用本机字节序来编码结构,并希望将数据移植到的下一个出色的操作系统不要大端字节序 。

mP. answered 2019-11-18T00:51:48Z

22 votes

ARM处理器(运行某些Android的ARM处理器)支持两种字节序格式。

在NDK-ROOT / platforms / android- [x] /arch-arm/usr/include/machine/endian.h中,您可以找到:

#ifdef __ARMEB__
#define _BYTE_ORDER _BIG_ENDIAN
#else
#define _BYTE_ORDER _LITTLE_ENDIAN
#endif

gcc编译器在使用BYTE_ORDER ARM选项时定义了#include 。即使大多数Android体系结构默认情况下都使用小尾数,您也不应将其视为理所当然,并且出于可移植性的原因,您的本机代码应能够处理两个尾数。

为此,您应该#include 并检查BYTE_ORDER以正确地构建代码。

mehi answered 2019-11-18T00:53:01Z

6 votes

为了提供非常简单的答案,以下是列表:

阿拉伯文:LITTLE_ENDIAN

armeabi-v7a:LITTLE_ENDIAN

arm64-v8a:LITTLE_ENDIAN

技巧:LITTLE_ENDIAN

mips64:LITTLE_ENDIAN

x86:LITTLE_ENDIAN

x86_64:LITTLE_ENDIAN

...从Android API级别21开始。

Ales Teska answered 2019-11-18T00:54:15Z
4 votes
bool isLittleEndian() {
unsigned short word=0x0102;
return *(char*)&word==2;
}

简单。

NoAngel answered 2019-11-18T00:54:34Z

0 votes

Android NDK具有以下宏,可用于在编译时进行检查:

#if defined(__LITTLE_ENDIAN_BITFIELD)
# error "Arch is Little Endian"
#elif defined (__BIG_ENDIAN_BITFIELD)
# error "Arch is Big Endian"
#endif

在您的情况下,您应该假设使用Little-Endian,并将其放置在Native源代码中的某个位置以下(如果有):

#if _BYTE_ORDER != _LITTLE_ENDIAN || defined (__BIG_ENDIAN_BITFIELD)
# error "Big-Endian Arch is not supported"
#endif
Top-Master answered 2019-11-18T00:55:04Z
0 votes
我尝试使用“ lx

gr”答案,也得到了LITTLE_ENDIAN。

但是在使用C ++时,我读取了一些包含以下信息的文件:50 4B 03 04 14 00 00 00 08 00 55 8A F4 3C 9B AA ...

我将前4个字节读取为UnsignedLong,得到67324752(以六进制表示)是:

4034B50

(前4位,但相反,好像我在使用BIG_ENDIAN拱门一样)

因此,可能是“ System.out.println(ByteOrder.nativeOrder());” 关于如何在Java中处理它们,但是要使用NDK在c ++中工作,您必须检查一下自己,这是一些缩小字节序的代码(从BIG_ENDIAN中的长期阅读开始):

long shrinkEndian(long value){
long result = 0;
result += (value & 4278190080) >> 24;
result += (value & 16711680) >> 8;
result += (value & 65280) << 8;
result += (value & 255) << 24;
return result;
}
Sebastian Corradi answered 2019-11-18T00:56:01Z