【问题标题】:How JNI works on the memory levelJNI 如何在内存级别上工作
【发布时间】:2017-06-29 17:45:16
【问题描述】:

我有一个 java 文件,它加载 .so 文件并打印来自 .so 文件的结果。我没有 .so 文件的源代码。谁能告诉我如何在内存结构中加载 .so 结果以及这个 Java 类从哪里读取 .so 生成的结果并将它们打印出来??

【问题讨论】:

    标签: android android-ndk java-native-interface jnienv


    【解决方案1】:

    如果您有任何已经用本地语言编写的代码并且不愿意更改它,但您希望在您的 java 代码中使用本地调用,而不是完全重写所有 java 代码。 JNI 派上用场了。它将所有特定于平台的实现转换为独立于平台的。标准库中对性能和平台敏感的 API 实现允许所有 Java 应用程序访问此功能。 库文件 .so 以这种方式进行转换。

    JNIEnv 包含从本地数据类型到 java 数据类型的所有类型转换。它还支持本地方法调用的合适实现,信号也由 JVM 处理。

    Java 是特定于硬件和操作系统平台的独立于平台的本机进程,通过将本机数据类型和方法调用映射到 java,它们都与平台无关。 JNI 使用库文件示例 .so 或 .a 文件执行上述操作

    对于 JNI 映射,您可以参考以下链接 http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html

    【讨论】:

    • 感谢您的回答。它确实有帮助。是的,我有一个用 Java 编写的代码,它加载了计算 CPU 使用率值的 libSSM.so。此 Java 程序打印来自 .so 文件的 android 应用程序的 CPU 使用率值。当然,Java 必须从内存中的某个位置读取这些值,所以想知道来自 .so 文件的内存结构值存储在哪里。
    【解决方案2】:

    您的 .so 有一个 JNI 粘合类,它将所有 Java 本地方法(public native void x();)与已编译的本地代码绑定。

    【讨论】:

      【解决方案3】:

      我假设它使用 JNI,否则我不知道它是如何工作的。如果它使用 JNI,那么它实际上会使用 JNI 库在 .so 中的 Java 堆上创建 Java 对象。查找标记为“native”的函数,这些函数直接映射到在 Java 代码运行库中的内容时调用的函数。

      【讨论】:

      • 感谢您的回答。是的,它使用 JNI,并使用 System.LoadLibrary(.so) 加载,但不知道函数映射。 Java 程序使用 libSSM.so 来监控 CPU 使用率并在 android 应用程序上打印结果。所以想知道 MainActivity.java 从哪里读取来自内存结构中编译的 C++ 代码的值。
      【解决方案4】:

      Droidfish Android chess game 写成Java。但是它的底层国际象棋引擎Stockfish是用C++写的。起初,我以为有一个JNI 层将这两者连接起来,但没有。 C++ stockfish 可执行文件启动,JavaC++ 通过stream 进行通信。

      您可以在命令行中启动 C++ stockfish 并使用该引擎,无需图形界面。

      在您的问题中,您的原生 .so 库正在向 stdout/stderr 打印一些内容,您想用 Java 读取这些输出吗?

      【讨论】:

        猜你喜欢
        • 2021-11-23
        • 2014-01-01
        • 1970-01-01
        • 2012-04-23
        • 2011-02-09
        • 2012-03-06
        • 2018-04-17
        • 2020-07-11
        • 1970-01-01
        相关资源
        最近更新 更多