Android заставляет OpenCV 3.0 загружаться как 32-битная библиотека

Я пытаюсь заставить свое 64-битное Android-устройство компилировать локальные 32-битные jniLibs, которые пока идут нормально, но я как бы столкнулся с загвоздкой.

Я исследовал, что именно пошло не так, в течение пары дней и возился здесь и там, но это текущая ошибка, которую я получаю:

java.lang.UnsatisfiedLinkError: dlopen failed: «/data/app/org.opencv.engine-1/lib/arm64/libopencv_java3.so» является 64-разрядным вместо 32-разрядного

Что на самом деле многообещающе, учитывая, что 64-битное устройство распознает, что оно должно компилировать 32-битную архитектуру, чего я достиг, опуская arm64, x86_64 и mips64, как согласно этому ответу: Android JNI: 32-разрядная совместимость с 64-разрядными устройствами?

Код инициализации, который я использую:

 OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);

Итак, мои вопросы заключаются в следующем:

  1. Есть ли способ отредактировать Abi, включенный в OpenCV 3.0, чтобы признать, что я хочу, чтобы 32-разрядная структура загружалась только после того, как устройство распознает, что оно должно искать только 32-разрядную структуру?

  2. Будет ли потеря функции хуже, если вернуться к OpenCV 2.4.11 (я знаю, что собственная камера не работает должным образом на новой платформе)

  3. Если ответ Abi правильный, будет ли он соответствовать сборке gradle на уровне приложения, уровне проекта или каком-либо другом (вероятно, opencvlib) уровне? Эта часть прошла мимо моей головы, читая другой ответ.


person KoalaKoalified    schedule 22.12.2015    source источник
comment
Я считаю, что это только одна из причин, почему при использовании собственного OpenCV с частными библиотеками JNI статическая ссылка предпочтительнее.   -  person Alex Cohn    schedule 22.12.2015
comment
Я могу заставить его загружаться правильно, когда включаю 64-битную версию armeabi-v8a/arm64, но библиотеки проекта, которые я хотел бы использовать, все 32-битные. Я также использую Android Studio в качестве IDE, но это не сильно отличается: импорт, создание build.gradle, включая jniLibs и их соответствующие подкаталоги, ссылки на уровне проекта и добавление зависимости модуля. EDIT: также после двойной проверки я m еще не загружаю свои пользовательские библиотеки и включил (насколько мне известно) только 32-битные библиотеки opencv   -  person KoalaKoalified    schedule 22.12.2015
comment
Я не думаю, что вы можете заставить OpenCVLoader с независимо установленным OpenCV Manager выбирать 32-битные библиотеки.   -  person Alex Cohn    schedule 22.12.2015
comment
Возможно, я неправильно понял, что на самом деле делает OpenCVLoader, и должен создавать все экземпляры по-другому.   -  person KoalaKoalified    schedule 22.12.2015
comment
После быстрого поиска я обнаружил, что OpenCVLoader.initDebug() будет просматривать только файлы приложения jni, но он не кажется очень стабильным в том смысле, что, если файлы не все так или иначе включены, я получаю массу исключений. ..   -  person KoalaKoalified    schedule 22.12.2015
comment
Возможно, мне просто нужно быть более усердным, но было бы неплохо, если бы я мог сказать OpenCVs Abi взаимодействовать только с 32-битными библиотеками.   -  person KoalaKoalified    schedule 22.12.2015
comment
Да было бы неплохо. Вы можете открыть запрос на веб-сайте OpenCV.   -  person Alex Cohn    schedule 22.12.2015
comment
Алекс и Коала - у меня такая же проблема, но вдобавок ко всему, я бы предпочел использовать статическую ссылку, а не заставлять моих пользователей также устанавливать OpenCV Manager. Любая идея, почему люди из OpenCV говорят, что статический подход к связыванию устарел?   -  person TonyC    schedule 04.01.2016
comment
Возможно, это связано с тем, что OpenCVManager не учитывает обновления OpenCV. Если вы следите за тем, работает ли ваше приложение в новых версиях, я думаю, его все еще можно использовать.   -  person KoalaKoalified    schedule 05.01.2016


Ответы (1)


Я установил его правильно, удалив все 64-битные библиотеки и сохранив все 32-битные библиотеки в папке jniLibs в приложении -> src -> main, но вместо вызова OpenCVLoader для загрузки библиотеки я просто сделал вызов следующим образом:

   if (!OpenCVLoader.initDebug()) {
        Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_1_0, this, mLoaderCallback);
    } 
    else {
        Log.d(TAG, "OpenCV library found inside package. Using it!");
        mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
    }

Который определяет, содержит ли ваше приложение локально файлы, которые OpenCVManager в противном случае обрабатывал бы. Еще одним преимуществом включения этих файлов в вашу папку jniLibs является то, что приглашение загрузить OpenCVManager больше не появляется, и ваше приложение по-прежнему имеет функциональность, как если бы пользователь имел ее.

Я предполагаю, что краткое руководство по реализации всего локально будет:

  1. Файл -> Создать -> Модуль импорта -> Перейти к OpenCV 3.1 -> sdk -> java

  2. Отредактируйте build.gradle нового модуля OpenCV, чтобы он соответствовал build.gradle вашего приложения.

  3. Щелкните правой кнопкой мыши папку приложения вашего проекта -> Открыть настройки модуля -> Зависимости -> + -> Зависимость модуля -> Выберите импортированную версию OpenCV

  4. Создайте папку в app -> src -> main с именем jniLibs (так как она называется по умолчанию, но ее можно редактировать в файле build.gradle)

  5. Перейдите в каталог OpenCV -> sdk -> native -> libs -> Скопируйте и вставьте armeabi, armeabi-v7a, mips в только что созданную папку jniLibs.

  6. Затем выполните инициализацию, используя приведенный выше пример кода, и OpenCV должен быть загружен локально.

person KoalaKoalified    schedule 05.01.2016
comment
как вы узнали, какие библиотеки были 64-битными? - person Libathos; 29.11.2016
comment
Как правило, очень мало, но официальное содержимое репо может работать с 64-битной архитектурой. - person KoalaKoalified; 04.12.2016