Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JNI - How to callback from C++ or C to Java?

I have Java application that invokes native C++/C code. The C++/C code needs to callback into Java. Could you give me some examples how to do this.

like image 727
garfield Avatar asked Mar 09 '12 06:03

garfield


People also ask

How do you call a function in C from Java?

To call a specific Java function from C, you need to do the following: Obtain the class reference using the FindClass(,,) method. Obtain the method IDs of the functions of the class that you want to call using the GetStaticMethodID and GetMethodID function calls.

How does JNI work in Java?

JNI provides functions for accessing the contents of array objects. While arrays of objects must be accessed one entry at a time, arrays of primitives can be read and written directly as if they were declared in C.

What is Jclass in JNI?

typedef jobject jclass; In C++, JNI introduces a set of dummy classes to enforce the subtyping relationship. For example: class _jobject {}; class _jclass : public _jobject {}; ...

What is JNA vs JNI?

Java Native Access (JNA) is a community-developed library that provides Java programs easy access to native shared libraries without using the Java Native Interface (JNI). JNA's design aims to provide native access in a natural way with a minimum of effort. Unlike JNI, no boilerplate or generated glue code is required.


1 Answers

There are many valid ways to callback into Java from C/C++. I'm going to show you a technique using C (easy to adjust env for C++) that makes it fairly easy to pass data from native code to Java code. This example passes strings ( easy to modify for any data type ).

In native code, create the following:

// Globals static jmethodID midStr; static char * sigStr = "(Ljava/lang/String;ILjava/lang/String;)V";  // Init - One time to initialize the method id, (use an init() function) midStr = (*env)->GetMethodID(env, class, "javaDefineString", sigStr);  // Methods static void javaDefineString(JNIEnv * env, jobject o, char * name, jint index, char * value) {   jstring string = (*env)->NewStringUTF(env, name);   (*env)->CallVoidMethod(env, o, midStr, string, index, (*env)->NewStringUTF(env, value)); } 

In Java code create the following:

Map<String, String>  strings = new HashMap<String, String>();  // Never call this from Java void javaDefineString(String name, int index, String value) {   String key = name + "." + index;   strings.put(key, value); } 

Native usage to send data:

javaDefineString(env, o, "Greet", 0, "Hello from native code"); javaDefineString(env, o, "KeyTimeout", 0, "one second"); javaDefineString(env, o, "KeyTimeout", 1, "two second"); 

Java usage to receive data:

System.out.println(strings.get("Greet.0"); System.out.println(strings.get("KeyTimeout.0"); System.out.println(strings.get("KeyTimeout.1"); 
like image 154
Java42 Avatar answered Sep 29 '22 20:09

Java42