I am new at using JNI. I successfully write a few programs that call native methods written in c.
Now I need my java code to be called by the native code side after it is initialized. Is it possible? Until now, I tried some kind of polling techniques. That is, I check native code parameters from my java code periodically, but if there is a way that native code can send some kind of interrupt it could be more efficient. Is it possible? Or can you suggest a better way than polling?
Note: When I search for "Call Java Functions from C Using JNI" all the answers I get is like
http://www.codeproject.com/Articles/22881/How-to-Call-Java-Functions-from-C-Using-JNI
JNI Call java method from c program
Those examples is not an answer for my situation. Because my main program is in java, and what I ask is that: Can the native functions(written in c) that I call from java code call some other java functions under certain circumstances? Is it possible to manage this without using a polling technique like I mentioned above?
Sure. It is actually easier than in the examples you linked because you don't have to spawn a JVM to do it -- the java functions that call you give you a pointer to the environment that you can use. As a simple example: With a Java class like this:
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");
}
}
And a library compiled from C code like this:
#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);
}
you would get the output
callback
static callback
If you don't get an object of the class you want to work with, you can use the FindClass
and NewObject
functions to make one, as in
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);
Further reading here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With