java - 从 C 调用 Java 方法而不从 C 启动 JVM

标签 java c java-native-interface jnienv

我正在寻找有关如何使用 JNI 从 C 调用 Java 方法的教程。到目前为止,在我找到的所有教程中,示例都展示了如何首先从 C 创建 JVM。

我的应用程序从 Java 开始,使用 JNI 调用一些 C 函数。我现在需要从 C 调用一些 Java 函数,我不想从 C 启动 JVM。

例如,是否有可能创建一个用 C 实现的“本地”方法,并使用它来保存 JNIEnv 指针,然后重用它,而不是创建一个来自 C 的新 JVM 实例,以便调用 Java 方法?

有例子吗?


编辑:

任何阅读此线程的人都应该小心! 仅使用来自当前 JNI 调用的 JNIEnv* 实例!如果您不想让程序崩溃,请不要保存和重复使用之前获得的任何 JNIEnv* 指针。

使用旧保存的指针,在最好的情况下可能会使您的应用程序崩溃。在更糟糕的情况下,它可能会导致难以调试和理解的低级不一致问题

不应缓存 JNIEnv* 实例,因为如果您的程序从 Java 开始,那么您的 C 代码将无论如何只能作为本地 java 方法执行,即它的 C 实现始终获取相关的 JNIEnv* 实例。这是您在 native 方法返回之前应该使用的唯一实例,而不是任何旧的已保存实例。

最佳答案

您可以使用 JNI_GetCreatedJavaVMs ( https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#JNI_GetCreatedJavaVMs ) 获取现有的 Java VM,而不是创建一个新的 Java VM(当当前进程已经有一个时这是不可能的)。使用 AttachCurrentThread ( https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/invocation.html#AttachCurrentThread ) 获取环境指针。

这也适用于多线程环境,而传递 env 指针仅适用于单线程。

关于java - 从 C 调用 Java 方法而不从 C 启动 JVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48487941/

相关文章:

c - 为什么 'typedef struct' 没有在 C 中成为可选的?

java - 如何找出当前具有焦点的对象

java - jsonschema2pojo.org 为 Json 对象生成的奇怪 Pojo

java - jsonSchema 用于验证有条件所需的属性

c - 数组位置自动变为1

c - 这个程序有什么问题吗?它无法正常运行

Android 鼠标光标事件/dev/uinput 不在 Y 轴上移动

c++ - 使用 JNI 将 jbyte 数组发送到 Java 方法失败

java - SoundPoolThread 通过 JNI 导致 SIGSEGV 错误 "accessed deleted global reference"

java - 失败的测试用例,我做错了什么?