无法使用 NDK 在 Android 工作室中从 .so 文件调用本机方法(加载库成功)


  1. 我创建了一个示例项目(HellWorldJNI),它与Android Ndk一起运行,并从本机C打印"来自Jni的Hello world"消息。

  2. 然后我从项目的输出/apk 目录中提取示例的 HelloWorldJNI.apk 文件。

  3. 所以我从不同的设备(如arm64-v8a,armeabi,x86)获得了所有.so文件。等)

  4. 现在我创建了一个新项目(CallJNIFromSoFile),并在主文件夹中创建了jniLibs文件夹,并将HelloWorldJNI应用程序的所有.so文件复制到这个新项目中。

  5. 之后,我像这样加载库和HelloWorldJNI应用程序的函数名称

    static {
        System.loadLibrary("hello-android-jni");
    }
    public native  static String getMsgFromJni();
    
  6. 在这里,我被击中了,我可以毫无问题地加载"hello-android-jni"库。但是上面的本机方法 getMsgFromJni() 以红色显示,并且无法调用该方法。

    根本没有收到消息"来自 Jni 的你好世界"

    这是我的日志输出:

    java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String
    at com.example.hari.myopencvvsample.MainActivity.getMsgFromJni(Native Method)
    

请建议我是否缺少上述步骤以外的任何内容。我尝试了很多方法,例如重新生成.so文件,然后再次放置,但没有奏效。 对不起我的英语。

提前谢谢。

您需要

提供方法getMsgFromJni()的 JNI 实现。.so文件是共享库,你可以链接到C或C++代码并使用它们,但你需要为你计划从Java调用的任何C或C++方法提供一个接口,因此Java Native Interface。

如果您查看 HelloWorldJNI 项目中的 src/main/jni 文件夹,您将看到一个 C 或 C++ 文件,该文件实现了该项目中从 Java 调用的任何本机方法。您还可以参阅 NDK 示例以获取更多帮助。hello-libs 示例是回答您问题的好起点。

Android项目之间复制*so文件是完全不好的主意。JNI将通过名称找到您的函数,该名称取决于您的Android应用程序java类层次结构的名称。因此,您的描述您首先编译了HelloWorldJni apk,并且您在那里有类似以下内容的符号:

T Java_com_example_helloworldjni_MainActivity_getMsgFromJni

如您所见,此函数的名称中包含您的 java 类层次结构。然后,您正在使用不同的类名创建自己的应用程序,并且您的程序查找类似以下内容的内容:

Java_com_example_hari_myopencvvsample_MainActivity_getMsgFromJni

在你的图书馆里,但如你所知 - 它不在那里。我建议您阅读这篇文章 https://developer.android.com/ndk/samples/sample_hellojni.html仔细地介绍 C 实现,并为您的新 CallJNIFromSoFile 项目重复所有步骤。

使用小于 23 的 targetSdkVersion 它将正常工作。

         defaultConfig {
             versionCode 1
             versionName "1.0.0"
             minSdkVersion 15
             targetSdkVersion 22

最新更新