【问题标题】:Calling C external library (.so) from android java从android java调用C外部库(.so)
【发布时间】:2021-09-07 13:46:23
【问题描述】:

我正在编写一个示例 android 应用程序来演示我们的(大学研究)C/C++ 库的使用。

我知道,使用 jni,我们可以从 java 调用 C 函数。 但是,我还没有找到关于如何在 Android Studio Artic Fox 中执行此操作的分步说明。

我已经看到需要编写与 jni 兼容的 C 包装函数,但还没有找到如何做到这一点(正确形成函数签名)或将它们放在哪里。

此外,我需要在项目设置中进行哪些更改才能正确构建项目(使用 gradle)?

请注意,我必须直接使用预构建的 .so 文件和为库定义一组公共 C 函数的公共头文件。

有很多示例提供了部分过时的信息,但仍然没有全面的信息 - 或者我错过了什么?

【问题讨论】:

  • 答案很大程度上取决于所说的库的作用。它是一个图像处理库吗?联网?声音的?请修改您的问题,了解您希望如何展示该功能。
  • 不,它是一个文本到语音库,所以没有与 UI 交互。
  • 好的,所以从一个简单地在循环中调用native static 函数的线程开始。为调用您的库的上述native 函数编写一些JNI 代码。
  • 这就是这个问题的重点:如何编写 jni 代码 - 函数签名,正确调整 gradle 构建,将 jni 代码文件放在哪里(我认为是 .c 和 .h),等
  • Android 开发者网站上有大量关于如何入门的文档。而且我不知道您为什么需要了解 gradle build 的详细信息,只需创建一个新的 JNI 项目并从那里开始工作?我可以执行 File -> New 并选择 Native C++,这是新的“完全原生”活动。或者,我可以创建一个常规的 Android 应用程序,右键单击该应用程序并说“将 C++ 添加到模块”为我生成必要的 CMake 内容。

标签: android-ndk java-native-interface


【解决方案1】:

我在下面整理了一份快速指南,但我想先澄清一下它们是如何组合在一起的。 在 Android 应用程序中,您可以将 native 方法绑定到从本机库加载的特殊命名的函数。 这些特殊命名的函数接收指向 JNIEnv 结构的指针,以与嵌入的 Java 应用程序进行交互。

本机库通常使用 CMake 构建。任何外部依赖项(例如您的预构建库)都需要在其 CMakeLists.txt 中对 CMake 可见。这里选择的武器是 IMPORTED 库,这正是您所认为的。

步骤

首先,创建一个以 Kotlin 为语言的 Android 项目。
右键单击树顶部的应用程序并选择“将 C++ 添加到模块”以生成必要的构建内容。

将您的 MainActivity.kt 文件更改为:

class MainActivity : AppCompatActivity() {
    external fun doit();
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val nativeThread = Thread {
            doit()
        }
        nativeThread.start()
    }
}

您将收到一个构建错误,指出“无法解析相应的 JNI 函数”。如果您为此选择快速修复,Android Studio 将生成一个 .cpp 文件,其中包含适当的 JNI 包装器代码。

生成的函数如下所示:

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myapplication_MainActivity_doit(JNIEnv *env, jobject thiz) {
    // TODO: implement doit()
}

以上将是有关如何从 Kotlin 加载本机库的说明。将该代码复制到您的 MainActivity.kt。

编辑该 .cpp 文件以使用您的本地库执行您需要执行的任何操作(例如 #include 一些文件并调用一些函数)。

最后,将app/src/main/cpp/CMakeLists.txt 编辑为point to your headers and precompiled library

【讨论】:

  • 感谢您提供此示例。我正在使用 Java,但我认为步骤大致相同。所以我会试一试:-)
  • 写完这一切后,我意识到“Native C++”模板已经为你做了什么......
  • 好吧,还在挣扎!我在哪里可以找到这个“Native C++”模板?它在我的“新文件”类型列表中不可用
  • 是file -> new -> new project下的选项之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 2017-10-18
  • 2011-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多