Android交叉编译JNI->未找到实现

时间:2020-02-03 15:21:08

标签: android c android-studio java-native-interface shared-libraries

我在Android应用中使用共享库libToon-c.so。

通过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进行了编译:

  • 使用aarch64-linux-android工具链的arm64平台
  • 使用i686-linux-anrdoid工具链的x86平台

为了将库包含在项目中,已按照以下方式将.so文件放入jniLibs文件夹中:

  • src / main / jniLibs / arm64-v8a(包含arm64库)
  • 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)的app文件夹中

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

按照指定的@Botje在.cpp和.h文件(如下)中添加了以下JNI_OnLoad。成功加载的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;
}

0 个答案:

没有答案