Calling Java methods from native code using JNI
I'm new to JNI I have successfully written some programs that call native methods written in C language
Now I need to call my java code from the native code side after initialization Is it possible? So far, I have tried some polling technology That is, I regularly check the native code parameters in my java code, but it may be more effective if the native code can send some kind of interrupt Is it possible? Or can you suggest a better way than voting?
Note: when I search for "calling Java functions from C using JNI", all the answers I get are
http://www.codeproject.com/Articles/22881/How-to-Call-Java-Functions-from-C-Using-JNI
JNI Call java method from c program
These examples do not solve my situation Because my main program is in Java, I want to ask: is the native function I called in Java code (written in C) able to call some other Java functions in some cases? Can I manage it without using the polling technology mentioned above?
Solution
of course. It's actually easier than your linked example because you don't have to generate a JVM to execute it – calling your Java function gives you a pointer to the environment you can use Take a simple example: use this 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"); } }
The libraries compiled from C code are as follows:
#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,"callback_static","()V"); // then call them. (*env)->CallVoidMethod (env,foo_obj,mid_callback); (*env)->CallStaticVoidMethod(env,mid_callback_static); }
You will get the output
callback static callback
If there is no object of the class to be used, you can use the findclass and newobject functions to create one, such as
jclass cls_foo = (*env)->FindClass (env,"foo"); jmethodID ctor_foo = (*env)->getmethodID(env,"<init>","()V"); jobject foo_obj = (*env)->NewObject (env,ctor_foo);
Read here