Basically, you don't call an existing library from Java using JNI; You create a new shared library that exports JNI-compatible functions that happen to use whatever libraries you need to implement them.
To use JNI, you:
- decide on a natural, Java-centric model (classes and methods) for the functionality you need
- add
native
to the declaration of the methods - compile the .java files to .class files using
javac
- run
javah
on the classes, passing a classpath, which is similar to runningjava
- implement the C functions emitted into the header. (You can use either C or C++ syntax)
- if a function implementation requires many Java type conversions or other manipulations in JNI code, go back to the Java class and do the manipulations there, moving
native
to aprivate
method that is easier to implement in JNI code than the original Java-centric method. (An example of this is string manipulations, where it can be easier for an implementation to consume a JavaString
as a Javabyte[]
with the character set/encoding needed by the libraries you use)
A function implementation usually follows the input-processing-output pattern: converting data from the Java parameters into C/C++ data types, calling a library function for processing and then converting data from C/C++ data structures to the Java return object.
You can also create Java objects, call methods and explicitly throw Java exceptions with JNI code.
And always be mindful that a JNI call can leave a Java exception thrown into the JVM, in which case you need to check and branch in your C/C++ code. When you want to leave the exception as thrown, you should stop calling other JNI functions, clean up and exit the function.
And, of course, all C++ exceptions must be caught and handled appropriately.
Alternatives (that actually use JNI under the covers):
- SWIG
- JNA, JNAerator
These take the opposite approach: take a (sometimes simplified or annotated) C or C++ header and create code that calls functions defined in it. You then might build up a Java model around it to make it more natural to call in your application code.