使用jni从本地代码调用Java方法

7

我刚开始使用JNI,成功地编写了几个调用C语言本地方法的程序。

现在我的Java代码已经初始化完成后需要由本地代码调用。这可能吗? 目前为止,我尝试了一些轮询技术。也就是说,我定期从我的Java代码中检查本地代码参数,但如果有一种方式可以发送某种类型的中断,那么它可能更有效。这可能吗?或者你能提供比轮询更好的方法吗?

备注: 当我搜索“使用JNI从C调用Java函数”时,所有答案都像下面这样:

http://www.codeproject.com/Articles/22881/How-to-Call-Java-Functions-from-C-Using-JNI

JNI Call java method from c program

这些例子都不是我需要的答案。因为我的主要程序是在Java中,我想问的是:我从Java代码中调用的本地函数(用C编写)是否可以在特定情况下调用其他Java函数?这是否可能在不使用我上面提到的轮询技术的情况下管理?


2
仅同步应该非常容易,即Java调用一个C函数,该函数调用一个Java函数并返回。 (更棘手的是,如果您的C函数正在设置一个后台线程,该线程在随机时间独立调用Java函数。) - Kerrek SB
1个回答

23
当然。实际上比你链接的示例更容易,因为你不需要生成JVM来执行它--调用你的java函数会给你一个指向环境的指针,你可以使用它。作为一个简单的例子:有一个这样的Java类:
public class foo {
  static {
    // load libfoo.so / foo.dll
    System.loadLibrary("foo");
  }

  private native void nativecall();

  public static void main(String[] args) {
    foo f = new foo();

    f.nativecall();
  }

  public void callback() {
    System.out.println("callback");
  }

  public static void callback_static() {
    System.out.println("static callback");
  }
}

而且还有一个从C代码编译而来的库,就像这样:

#include <jni.h>

JNIEXPORT void JNICALL Java_foo_nativecall(JNIEnv *env, jobject foo_obj) {
  // Get the class from the object we got passed in
  jclass cls_foo = (*env)->GetObjectClass(env, foo_obj);

  // get the method IDs from that class
  jmethodID mid_callback        = (*env)->GetMethodID      (env, cls_foo, "callback"       , "()V");
  jmethodID mid_callback_static = (*env)->GetStaticMethodID(env, cls_foo, "callback_static", "()V");

  // then call them.
  (*env)->CallVoidMethod      (env, foo_obj, mid_callback);
  (*env)->CallStaticVoidMethod(env, cls_foo, mid_callback_static);
}

你会得到输出

callback
static callback

如果您无法获取想要使用的类的对象,则可以使用FindClassNewObject函数创建一个对象,例如:

如果您要使用的类的对象不存在,则可以使用FindClassNewObject函数创建一个对象,如下所示:

jclass    cls_foo  = (*env)->FindClass  (env, "foo");
jmethodID ctor_foo = (*env)->GetMethodID(env, cls_foo, "<init>", "()V");
jobject   foo_obj  = (*env)->NewObject  (env, cls_foo, ctor_foo);

深入阅读 这里


工作在本地调用内。链接已失效。 - Sam Ginrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接