3

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.

Tomáš Zato
  • 853
  • 1
  • 10
  • 20

2 Answers2

4

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

rwong
  • 16,695
  • 3
  • 33
  • 81
  • Could you please explain further what *C JNI wrapper* is supposed to do? I mean I was going to wrap procedural C code into OOP C++ one, then build `.so` files out of that OOP code. – Tomáš Zato Sep 06 '15 at 12:55
  • @TomášZato Probably something like the member access examples in [SWIG documentation](http://www.swig.org/Doc3.0/SWIGPlus.html#SWIGPlus_nn11). – han Sep 06 '15 at 14:26
  • @TomášZato I added more explanation. Btw, the best way is to read the official JNI documentation. I don't have much confidence in my explanation. You may find a lot of "why wasn't JNI designed the other way around?" and the answer would be "because it *was* designed that way." There are actually many other JNI wrapper creation technologies around; but many of them were abandoned or unmaintained. – rwong Sep 06 '15 at 16:05
  • 1
    @rwong: another thing to look at is [JNAerator](https://github.com/nativelibs4java/JNAerator) Which skips the C layer entirely. – SailsMan63 Sep 08 '15 at 13:08
0

Yes you can use JNI for this, even with objects... if it makes sense is another question.

Put wiringPi into a own C++ library seems a little bit strange to me because you can use the library, even in c++ code and the method calls are really simple. Here's an tutorial how to use JNI with c++: wrapping a c library with JNI

wiringPi is C based, this way I wouldn't create a c++ lib for use with JNI, just write a wiringPI-wrapper/adapter for your JNI calls in C?!

ChrisF
  • 38,878
  • 11
  • 125
  • 168
Wolfgang
  • 131
  • 3
  • If you ever happen to use some embed system C++ library, take closer look at it - you'll find out it's just encapsulating a procedural C library. I pretty much believe `gcc` can optimize it completely. – Tomáš Zato Sep 06 '15 at 12:54