Android JNI не может успешно загрузить библиотеку с помощью dlopen - но раньше - PullRequest
0 голосов
/ 17 мая 2018

Это история двух (фактически четырех) устройств Android.Только один из них является телефоном и не имеет отношения к проблеме.

Мой JNI работает на одном, но не на других.

До недавнего времени это приложение и его JNI работали нормально.После того, как мне не нужно было вносить какие-либо обновления в течение года, я снова открыл его, и теперь произошел сбой.

Этот код JNI (с несколькими изменениями имени, чтобы запутать проект на общедоступном форуме):

void * gTheLibrary;
JNIEXPORT int JNICALL Java_com_doamin_ourapp_ourmodule_LoadLib(JNIEnv * env, jobject obj) {
    globalObject = env->NewGlobalRef( obj );
    env->GetJavaVM( &globalJVM );
    if (gTheLibrary != NULL) {
        __android_log_print(ANDROID_LOG_VERBOSE, APPNAME," JNI-> The lib is already loaded\n");
        return 0;
    }
    gTheLibrary = dlopen("./libmyprocess.so", RTLD_NOW);
    if (gTheLibrary == NULL) {
        char buffer[512];
        sprintf(buffer," JNI-> ****  FAILED to load DSO %s \n", dlerror());
        __android_log_print(ANDROID_LOG_VERBOSE, APPNAME,"%s",buffer);
        return -1;
    }
...

Отчеты о записи в журнале "dlerror ()":

"JNI-> ****  FAILED to load DSO dlopen failed: library "./libmyprocess.so" not found"

Но библиотека C поставляется с APK.Итак, модуль C lib для этого JNI загружается.Но это вызов «dlopen ()» не находит DSO.

Как я уже сказал, этот код используется для работы на всех устройствах.Пока я не открыл проект, чтобы внести некоторые незначительные изменения.И ни один из них не связан с JNI.Небольшие изменения в Java.

  • Этот код отлично работает в Kindle Fire, версия для Android 5.0.1
  • Этот код не срабатывает на «dlopen (...)» на SamsungПланшет 10.1 "Android 6.0.1
  • Этот код не работает на HTC Desire 530, Android 7.0
  • Этот код также отлично работает на Odroid SBC под управлением Android 4.4

Все устройства были настроены так, чтобы разрешать отладку по USB, разрешать приложения из неизвестных источников и т. Д ... Повторяю, это работало для всех этих устройств с. Теперь оно не работает на некоторых из них.

В библиотеке JNI и библиотеке, которую она пытается загрузить, для Application.mk установлено значение «APP_PLATFORM: = android-19», поэтому они согласованы. Библиотеки создаются вне Android Studio, поэтому версияне должно быть фактором, но я использую AS 2.3.3. Я перекомпилировал все , чтобы сохранить синхронизацию.

Я предполагаю, что это связано сверсия ОС. Но не приводит к тому, что / почему это отличается для скомпилированного Cкод.И почему на тех же версиях ОС это сработало год назад.Есть ли какой-нибудь совет, который может быть предложен, чтобы помочь определить, как обойти это?

Заранее спасибо.

-Scotty

---- ОБНОВЛЕНИЕ -----
Пытаться, а не прогрессировать ... Используя "arm-linux-androideabi-readelf", я вижу, что есть 6 библиотек "NEEDED":

0x00000001 (NEEDED)   Shared library: [liblog.so]
0x00000001 (NEEDED)   Shared library: [libandroid.so]
0x00000001 (NEEDED)   Shared library: [libstdc++.so]
0x00000001 (NEEDED)   Shared library: [libc.so]
0x00000001 (NEEDED)   Shared library: [libm.so]
0x00000001 (NEEDED)   Shared library: [libdl.so]

Я полностью выпотрошил библиотеку, ивосстановил это.Даже не #include ... Это буквально так:

void * Initialize() {
    return 0;
}

Буквально не нужно никаких внешних библиотек.И все же я перезапустил «arm-linux-androideabi-readelf», и в все еще перечислены те же 6 библиотек .И когда я повторно тестирую приложение, оно все равно не загружается.

В качестве другого теста я взял эти 6 необходимых библиотек из ... \ platform \ android-19 \ arch-arm \ usr \ lib \ и скопировалпоместите их в ту же папку «libs», что и JNI, и библиотеку в dlopen (...) и проверили, что все они находятся в APK (открыв его в виде zip-файла).Но DSN JNI все еще дает мне ту же ошибку на «dlopen (...)».

И мой разум продолжает возвращаться к старой поговорке «Это работало раньше» - что изменилось вустройства?Или какое-нибудь автообновление в Studio / NDK?

1 Ответ

0 голосов
/ 17 мая 2018

Это было исправлено путем устранения «локального» пути ...

 gTheLibrary = dlopen("libmyprocess.so", RTLD_NOW);

Я не уверен, почему он был там изначально.Я предполагаю, потому что 2 года назад необходимо было указать местное местонахождение библиотеки.Теперь, однако, это вызывает проблему.Нет необходимости включать 6 «необходимых» библиотек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...