Java and C++ – How to Import C++ Classes Using JNA or JNI

cdynamic-linkingjava

In past, I used JNI to access some winapi functions, however winapi is C and therefore just procedural. Now my plan is different and I need to know whether I'm going in the right direction. What I want is:

  • to make a dynamic C++ OOP library for Linux (Debian) that, possibly based on WiringPi C library, allows object oriented approach to Raspberry PI GPIO
  • wrap this library in Java classes.

Note that I am also planning to use the library in it's original form, but in some cases I will need to just add the WiringPI functionalities to existing Java programs.

I am asking here because Google has failed me on figuring out whether my plan is possible and sane.

Best Answer

The recommended way is to read carefully the official JNI documentation.


(Disclaimer: my description below may contain errors.)

This requires not one, but two layers of wrappers (item 2 and 3):

  • Java application code
  • Java JNI wrapper classes (to give an object model to the library)
  • C JNI wrapper (to marshal the data between JNI environment and C/C++ code)
  • C++ library code

The C JNI wrapper is responsible for gaining access to Java arrays, strings, object member fields, etc. This is necessary because Java can move around arrays and objects in memory, as part of garbage collection. In some sense, C code cannot get hold of anything in the Java environment unless it obtains a reference (which signifies the thing's lifetime to the VM). Even so, one can only obtain addresses of arrays if the array and the VM support pinning (being pinned down at its current memory address). Otherwise, every access to Java data requires copying, and this copying can only be performed with the help of the JNI.

The C JNI function cannot be a class member function, by design. To be able to call C++ object member functions, the C JNI method must obtain the address of the C++ object (typically stored as a 32-bit or 64-bit integer field in the Java JNI wrapper class), and cast it into the C++ object pointer.

The biggest problems are:

  • It is hard for wrapper generators to generate a satisfactory Java object model given the C/C++ code, regardless of whether the latter was written in an OOP style. Wrapper generators written in the last decade do not understand C/C++ styles deep enough to be able to recognize OOP idioms. (Most might even fail to parse legal C/C++ code, due to the language's syntax complexity.)

  • A human wrapper-writer will make plenty of style adaptations between the two languages. Until recently, it was hard to imitate such preferences (which are not mechanical and not straightforward) in wrapper generators.

Please also take a look at

Related Topic