Android Кросс-компиляция JNI -> Не найдена реализация для - PullRequest
1 голос
/ 03 февраля 2020

Я использую общую библиотеку libToon- c .so в своем приложении android.

При запуске этого приложения через виртуальное устройство Android (AVD) загружаемая общая библиотека работает без проблем.

Однако при попытке загрузить библиотеку на телефон (Google Pixel) отображается следующая ошибка

E/linker: "/data/app/com.example.androidsharedlibscratch-a6Mv8edOnQ2q6HbbixecrQ==/lib/arm64/libToon-c.so": ignoring DT_PREINIT_ARRAY in shared library! E/haredlibscratc: No implementation found for long com.example.androidsharedlibscratch.Toon.createToon() (tried Java_com_example_androidsharedlibscratch_Toon_createToon and Java_com_example_androidsharedlibscratch_Toon_createToon__) D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.androidsharedlibscratch, PID: 18368
    java.lang.UnsatisfiedLinkError: No implementation found for long com.example.androidsharedlibscratch.Toon.createToon() (tried Java_com_example_androidsharedlibscratch_Toon_createToon and Java_com_example_androidsharedlibscratch_Toon_createToon__)
        at com.example.androidsharedlibscratch.Toon.createToon(Native Method)
        at com.example.androidsharedlibscratch.Toon.<init>(Toon.java:44)
        at com.example.androidsharedlibscratch.MainActivity.onCreate(MainActivity.java:41)
        at android.app.Activity.performCreate(Activity.java:7144)
        at android.app.Activity.performCreate(Activity.java:7135)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2931)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6718)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

toonJni.h содержит следующее определение функции

JNIEXPORT jlong JNICALL Java_com_example_androidsharedlibscratch_Toon_createToon
  (JNIEnv *, jobject);

Соответствующий файл toonJni. cpp содержит следующую реализацию функции:

JNIEXPORT jlong JNICALL Java_com_example_androidsharedlibscratch_Toon_createToon(JNIEnv *env, jobject obj) {
    ...
    return (reinterpret_cast<jlong>(toon));
}

Эта общая библиотека была скомпилирована для Android с использованием следующих автономных наборов инструментов:

  • arm64 платформа с использованием aarch64- linux - android набор инструментов
  • Платформа x86 с использованием i686- linux -anrdoid toolchain

Чтобы включить библиотеку в проект, файл .so был помещен в папку jniLibs, как показано ниже:

  • src / main / jniLibs / arm64-v8a (содержит arm6 4 библиотеки)
  • src / main / jniLibs / x86 (содержит библиотеку x86)

Следующий код был добавлен в build.gradle для включения файлов jni :

sourceSets {
        main {
            jniLibs.srcDirs 'src/main/jniLibs'
        }
    }

Файл toonJni.h содержит директиву extern c {...}

Файл toonJni.h сгенерированный с помощью следующей javac команды

javac -h . Toon.java

APK был собран, извлечен и проверен на наличие файла libToon- c .so

Следующие команды также используются для проверки того, что libToon- c .so находится в папке приложения на устройстве (Google Pixel)

adb shell dumpsys package packages | grep androidsharedlibscratch
adb ls /data/app/com.example.androidsharedlibscratch-foqHDywOpE_dDPgTCtTttw==/lib/arm64

Ниже приведены команда и результаты проверки искажения имени:

android-ndk-r21/build/toolchain/bin/aarch64-linux-android-nm android_studio_scratch/AndroidSharedLibScratch/app/src/main/jniLibs/arm64-v8a/libToon-c.so

000000000000d570 T Java_com_example_androidsharedlibscratch_Toon_createToon

Добавлен следующий JNI_OnLoad в файлы. cpp и .h (ниже) как @ Ботье указано. Успешно загруженная toonLib не отображается в android studio logcat (для уровня журнала задано подробное значение).

Определение в toonJni.h:

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved);

Реализация в toonJni. cpp:

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    JNIEnv* env;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        return JNI_ERR;
    }

    __android_log_print(ANDROID_LOG_INFO, "toonlib", "toonlib loaded successfully");

    return JNI_VERSION_1_6;
}
...