Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data types from Java to C (or vice versa) using JNI

Using JNI can we pass custom data types from Java to C (or vice versa)? I see a mapping of primitive datatypes to types in C however not too sure if we can send across our own data types (e.g. Send across or return an Employee object or something!).

like image 921
user277460 Avatar asked Mar 23 '10 23:03

user277460


People also ask

How does JNI work in Java?

It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.

What is a JNI method?

In software design, the Java Native Interface (JNI) is a foreign function interface programming framework that enables Java code running in a Java virtual machine (JVM) to call and be called by native applications (programs specific to a hardware and operating system platform) and libraries written in other languages ...

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.

What is Jclass in JNI?

The jclass instance is your object on which a method will be invoked; you'll need to look up the getName method ID on the Class class, then invoke it on the jclass instance using CallObjectMethod to obtain a jstring result. So in short yes, you just call the getName function and look at the jstring result.


1 Answers

If you're going to be doing this with a lot of objects, something like Swig would be best. You could use jobject type to pass around custom objects. The syntax isn't nice, perhaps there is a better way to write this.

Example Employee object:

public class Employee {     private int age;      public Employee(int age) {         this.age = age;     }      public int getAge() {         return age;     } } 

Call this code from some client:

public class Client {     public Client() {         Employee emp = new Employee(32);          System.out.println("Pass employee to C and get age back: "+getAgeC(emp));          Employee emp2 = createWithAge(23);          System.out.println("Get employee object from C: "+emp2.getAge());     }      public native int getAgeC(Employee emp);     public native Employee createWithAge(int age); } 

You could have JNI functions like this for passing an employee object from Java to C, as a jobject method argument:

JNIEXPORT jint JNICALL Java_Client_getAgeC(JNIEnv *env, jobject callingObject, jobject employeeObject) {     jclass employeeClass = (*env)->GetObjectClass(env, employeeObject);     jmethodID midGetAge = (*env)->GetMethodID(env, employeeClass, "getAge", "()I");     int age =  (*env)->CallIntMethod(env, employeeObject, midGetAge);     return age; } 

Passing an employee object back from C to Java as a jobject, you could use:

JNIEXPORT jobject JNICALL Java_Client_createWithAge(JNIEnv *env, jobject callingObject, jint age) {     jclass employeeClass = (*env)->FindClass(env,"LEmployee;");     jmethodID midConstructor = (*env)->GetMethodID(env, employeeClass, "<init>", "(I)V");     jobject employeeObject = (*env)->NewObject(env, employeeClass, midConstructor, age);     return employeeObject; } 
like image 187
Stew Avatar answered Oct 02 '22 03:10

Stew