使用 jni 从本机代码调用 Java 方法
Calling a Java Method from the native code using jni
我刚开始使用 JNI。我成功地编写了几个调用用 c 编写的本机方法的程序。
现在我需要我的 java 代码在初始化后被本机代码端调用。可能吗?
到目前为止,我尝试了某种轮询技术。也就是说,我会定期检查 java 代码中的本机代码参数,但如果本机代码可以通过某种方式发送某种中断,则效率会更高。可能吗?或者你能推荐一个比轮询更好的方法吗?
注意:
当我搜索 "Call Java Functions from C Using JNI" 时,我得到的所有答案都是
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函数吗?是否可以在不使用我上面提到的轮询技术的情况下进行管理?
当然可以。它实际上比您链接的示例更容易,因为您不必生成 JVM 来执行它——调用您的 java 函数为您提供指向您可以使用的环境的指针。举个简单的例子:用 Java class 这样的:
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
如果你没有得到你想要使用的 class 的对象,你可以使用 FindClass
和 NewObject
函数来创建一个,如
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);
进一步阅读here。
我刚开始使用 JNI。我成功地编写了几个调用用 c 编写的本机方法的程序。
现在我需要我的 java 代码在初始化后被本机代码端调用。可能吗? 到目前为止,我尝试了某种轮询技术。也就是说,我会定期检查 java 代码中的本机代码参数,但如果本机代码可以通过某种方式发送某种中断,则效率会更高。可能吗?或者你能推荐一个比轮询更好的方法吗?
注意: 当我搜索 "Call Java Functions from C Using JNI" 时,我得到的所有答案都是
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函数吗?是否可以在不使用我上面提到的轮询技术的情况下进行管理?
当然可以。它实际上比您链接的示例更容易,因为您不必生成 JVM 来执行它——调用您的 java 函数为您提供指向您可以使用的环境的指针。举个简单的例子:用 Java class 这样的:
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
如果你没有得到你想要使用的 class 的对象,你可以使用 FindClass
和 NewObject
函数来创建一个,如
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);
进一步阅读here。