【问题标题】:Unable to call Native method from .so file (Loading of library is success ) in Android studio With NDK无法使用 NDK 在 Android Studio 中从 .so 文件调用 Native 方法(库加载成功)
【发布时间】:2017-07-20 19:52:49
【问题描述】:
  1. 我创建了使用 Android Ndk 运行的示例项目 (HellWorldJNI),并从本机 C 打印“Hello world from Jni”消息。

  2. 然后我从项目的Output/apk目录中提取样本的HelloWorldJNI.apk文件。

  3. 所以我得到了来自不同设备(如 arm64-v8a、armeabi、x86..等)的所有 .so 文件

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

  5. 之后我像这样加载HelloWorldJNI App的库和函数名

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

    完全没有收到消息“来自 Jni 的 Hello world”

    这是我的 Logcat 输出:

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

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

提前致谢。

【问题讨论】:

  • 我正在为同样的事情苦苦挣扎!请问你最后是怎么解决的?谢谢!

标签: android android-ndk


【解决方案1】:

您需要提供方法getMsgFromJni() 的JNI 实现。 .so 文件是共享库,您可以链接到 C 或 C++ 代码并从中使用,但您需要为计划从 Java 调用的任何 C 或 C++ 方法提供接口,因此 J ava Native I界面。

如果您查看 HelloWorldJNI 项目中的 src/main/jni 文件夹,您将看到一个 C 或 C++ 文件,该文件实现了该项目中从 Java 调用的任何本机方法。您也可以参考NDK samples 获取更多帮助。 hello-libs example 是您开始提问的好地方。

【讨论】:

  • 感谢您的回答。它已经实现了方法 getMsgFromJni() 并且在我运行我的项目 HelloWorldJNI 时运行良好。
  • 它在我的方法实现中显示类似“Hello world from Jni”的消息。但是在我的第二个项目(CallJNIFromSoFile)中,我只复制了 HelloWorldJNI 项目的 .so 文件,并加载库并像这样调用 getMsgFromJni() 方法 static { System.loadLibrary("hello-android-jni"); } 公共原生静态字符串 getMsgFromJni();这是它不起作用的地方。
  • 是的,因为您只复制了 .so 文件。您可以在预构建的库上创建依赖项,但如果不提供 JNI,您将无法使用它们。
  • 那么如何创建 jni @Francesca Nannizzi
【解决方案2】:

在 Android 项目之间复制 *so 文件是完全糟糕的想法。 JNI 将通过名称查找您的函数,该名称取决于您的 Android 应用程序 java-class 层次结构的名称。 因此,您的描述首先编译了 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 项目重复所有步骤。

【讨论】:

  • 感谢您的回答。场景是这样的。我有您通过构建 A 生成的项目 A 和 A.SO。现在,我想要项目 B,我想在项目 B 中使用 A.SO。项目 B 是简单的 Android 项目而不是本机。
【解决方案3】:

使用小于 23 的 targetSdkVersion 会正常工作..

         defaultConfig {
             versionCode 1
             versionName "1.0.0"

             minSdkVersion 15
             targetSdkVersion 22

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-02
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多