Endianness Android NDK - PullRequest
       1

Endianness Android NDK

53 голосов
/ 02 июня 2011

Я работаю с моим новым приложением, которое обрабатывает захваченное изображение с камеры мобильного телефона. Мой телефон Nexus S, 2.3.4.

Я создаю растровое изображение ARGB_8888 с захваченными данными. Я знаю lib ndk image, но он поддерживает только 2.2 и выше. Поэтому я передаю int [] Bitmap в NDK и обнаруживаю, что порядок цветовых байтов имеет порядок байтов.

Я искал вики и обнаружил, что архитектура рук является bi-endian. http://en.wikipedia.org/wiki/Endianness#Bi-endian_hardware

Мой вопрос: если рука является bi-endian, как определить порядок байтов в конкретном устройстве? Должен ли я проверять порядок байтов каждый раз, прежде чем получить доступ к данным?

Ответы [ 7 ]

42 голосов
/ 29 октября 2011

Непосредственно от моего Nexus S:

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

Также должен быть какой-то способ получить заказ в NDK.

37 голосов
/ 14 июля 2011

Да, большинство процессоров с би-прямым порядком байтов, но большинство операционных систем для конечных пользователей, которые используются сегодня, предпочитают использовать процессоры с прямым порядком байтов. Вдобавок к этому ARM может работать в обоих случаях для удобства, его фактическое значение по умолчанию после ARM 3 - это метод с прямым порядком байтов, который является порядком байтов, в котором он запускается. Я думаю, можно смело предположить, что все устройства Android имеют младший порядок байтов, иначе это будет будь дополнительной работой, если разные андроид устройства были смесью endianess.

Поскольку порядок байтов в сети имеет порядок байтов, может быть полезно преобразовать любой формат, который вы планируете использовать для обмена данными, в порядок байтов в сети. Тем не менее, Mac OS X на процессорах Intel, Windows, iOS и Android также имеет младший порядок байтов, поэтому вы можете просто кодировать структуры с исходным порядком байтов и надеяться, что следующая отличная ОС, для которой вы хотите портировать данные, не превратится в последовательность байтов. .

22 голосов
/ 08 февраля 2012

ARM процессоры (на которых работает Android) поддерживает оба формата endian .

В NDK-ROOT / platform / android- [x] / arch-arm / usr / include / machine / endian.h вы можете найти:

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

__ARMEB__ определяется компилятором gcc при использовании опции -mbig-endian ARM .Даже если в большинстве архитектур Android по умолчанию используется порядок байтов с прямым порядком байтов, вы не должны принимать это как должное, и по причинам переносимости ваш нативный код должен иметь возможность обрабатывать оба порядка байтов.

Для этого вам необходимо #include <endian.h> и проверитьBYTE_ORDER для правильной архитектуры вашего кода.

5 голосов
/ 02 ноября 2016

Чтобы дать очень простой ответ, вот список:

  • armeabi: LITTLE_ENDIAN
  • armeabi-v7a: LITTLE_ENDIAN
  • arm64-v8a: LITTLE_ENDIAN
  • mips: LITTLE_ENDIAN
  • mips64: LITTLE_ENDIAN
  • x86: LITTLE_ENDIAN
  • x86_64: LITTLE_ENDIAN

... с API Androidуровень 21.

4 голосов
/ 22 апреля 2015
bool isLittleEndian() {
    unsigned short word=0x0102;
    return *(char*)&word==2;
}

простой.

0 голосов
/ 09 ноября 2018

Я попытался с ответом "lxgr", и я также получил 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, но, работая в c ++ с NDK, вам придется проверить себя, вот некоторый код для сокращения endiannes (из давно прочитанного в 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;
}
0 голосов
/ 19 марта 2018

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 и поместить где-нибудь ниже в исходном источнике, если он есть:1004 *

#if _BYTE_ORDER != _LITTLE_ENDIAN || defined (__BIG_ENDIAN_BITFIELD)
#  error "Big-Endian Arch is not supported"
#endif
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...