Android-NDK的终结性

Android-NDK的终结性,android,android-ndk,Android,Android Ndk,我正在使用我的新应用程序处理手机摄像头拍摄的图像。我的手机是NexusS,2.3.4 我用捕获的数据创建了一个ARGB_8888位图。我知道ndk映像库,但它只支持2.2及以上版本。因此,我将位图的int[]传递给NDK,发现颜色字节顺序是little endian 我搜索了维基,发现arm架构是双端的。 我的问题是,如果arm是双端的,如何判断特定设备中的字节顺序?是否每次访问数据前都要测试字节顺序?是的,大多数CPU都是双端的,但目前使用的大多数最终用户操作系统都选择使用小端的CPU。沿着

我正在使用我的新应用程序处理手机摄像头拍摄的图像。我的手机是NexusS,2.3.4

我用捕获的数据创建了一个ARGB_8888位图。我知道ndk映像库,但它只支持2.2及以上版本。因此,我将位图的int[]传递给NDK,发现颜色字节顺序是little endian

我搜索了维基,发现arm架构是双端的。


我的问题是,如果arm是双端的,如何判断特定设备中的字节顺序?是否每次访问数据前都要测试字节顺序?

是的,大多数CPU都是双端的,但目前使用的大多数最终用户操作系统都选择使用小端的CPU。沿着这些思路,ARM可以方便地在这两种模式下操作,它在ARM3之后的实际默认值是little Endianness,这是它启动时使用的endian模式。我认为可以有把握地假设所有Android设备都是little endian,否则如果不同的Android设备是endian的混合体,这将是额外的工作


因为网络字节顺序是big-endian,所以将您计划用于数据交换的任何格式转换为网络字节顺序都会很有帮助。不过,同样,英特尔、Windows、iOS和Android上的Mac OS X都是小endian,因此您可能只需使用本机endian编码结构,并希望下一个您想要将数据移植到的伟大操作系统不会变成大endian。

直接从我的Nexus S:

> import java.nio.*;
> System.out.println(ByteOrder.nativeOrder());
LITTLE_ENDIAN
在NDK中也应该有某种方式来获得排序。

处理器(一些Android正在运行)支持格式

在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
\uuuu ARMEB\uuuu
由gcc编译器在使用
-mbig endian
时定义。 即使大多数Android架构默认使用little endian,您也不应该认为这是理所当然的,出于可移植性的原因,您的本机代码应该能够处理这两个endian

为此,您应该
#包括
并检查
字节顺序
,以正确构建代码

bool isLittleEndian() {
    unsigned short word=0x0102;
    return *(char*)&word==2;
}

简单。

要提供非常简单的答案,请列出:

  • 阿梅亚比:小恩迪安
  • armeabi-v7a:小安迪安
  • arm64-v8a:LITTLE_ENDIAN
  • 小丁安
  • mips64:LITTLE_ENDIAN
  • x86:LITTLE_ENDIAN
  • x86_64:LITTLE_ENDIAN

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

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

#if defined(__LITTLE_ENDIAN_BITFIELD)
#  error "Arch is Little Endian"
#elif defined (__BIG_ENDIAN_BITFIELD)
#  error "Arch is Big Endian"
#endif
在您的情况下,您应该假设小端点,并将其放置在本机源中的某些位置(如果有)下方:

#if _BYTE_ORDER != _LITTLE_ENDIAN || defined (__BIG_ENDIAN_BITFIELD)
#  error "Big-Endian Arch is not supported"
#endif
我尝试了“lxgr”的答案,我也得到了LITTLE_ENDIAN

但是用C++工作,我用这个信息读取一些文件: 50 4B 03 0414 00 00 08 00 55 8A F4 3C 9B AA

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

4034B50

(前4位,但颠倒过来,好像我在做一个大拱门)

>,可能是“St.out。PrtLn(ByTeord.nTiValOrreDead));“如何处理java中的它们,但是C++中使用NDK工作,您必须检查自己,这里有一些收缩Channes的代码(从长在BigyNeNoDE中):< /P>

long shrinkEndian(长值){
长结果=0;
结果+=(值&4278190080)>>24;
结果+=(值&16711680)>>8;


结果+=(值&65280)我很惊讶这是必要的,双端性不意味着操作系统将在所有设备上配置一个通用的端格式吗?您是否遇到过颜色字节顺序不是小端的情况?自ARMv6以来,您可以动态切换ARM的端性,但iOS、Android和Windows(所有风格)使用little-endian。这在不同的设备上不会改变。谢谢你,Jodes和BitBank。看起来我应该只关注Android设备上的little-endian。相反,你可能会遇到的95%的计算机都是little-endian。Android不是台式机或其他大型计算机。它是关于手机,大多数平板电脑都是由智能手机驱动的RM CPU。似乎所有Android系统都是little endian。Android可能是little endian,但Java不是。:/我想说95%是一个巨大的低估。可能更接近99.99999%好答案,小更正:事实上,_BYTE_顺序是在NDK-ROOT/platforms/Android-[x]中定义的/arch arm/usr/include/machine/endian.h-1.随机定义ARMEB不会使字节顺序变为神奇的大端,它只会使字节顺序宏不正确。@NicholasWilson我已经明确说过你不应该定义ARMEB谢谢@MarkKahn的更正。我不确定它是否适用于所有SDK。@mehy Where?你的答案是建议在命令行上定义_ARMEB_u将影响您得到的endian,这是错误的。谢谢@NoAngel,但有时我们需要条件编译谢谢,但请提供一个源代码。@DroidCoder从Android NDK中提取。它在NDK中的什么位置?在little endian中,字节在内存和文件中反向存储,因此,上述行为(将
50 4B 03 04
解读为
0x04034B50
)对于小端机器是正确的,而不是您错误地宣称的大端机器。
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;
}