Hello community!
This is my first post, hope you like it! Notice that all content here is about my studies on JNI. Feel free to make suggestions, corrections, etc. :D
Good read!^^
NATIVE CALL FROM JAVA CODE TO C CODE.
The keyword "native" on Java allow us to call native libraries, by using the JNI.
That document was based on Baeldung post, Prof. Gustavo Leitão video and Oracle documentation about JNI.
1. Introduction
The JNI (Java Native Interface) allows Java to access codes on C and C++.
Commonly used for specifics performance cases, to handle hardwares or even use an existing library (not to need to rewrite).
2. The "native" key word.
When we are working with JNI, the native key word need to be used.
That key word says for JVM: "That method has an implementation on other language".
Here is an example of a native method:
public native void myNativeMethod();
Native methods are like abstracts one, with the difference that its implementation will be done in a separated native code file instead of a .java one.
3. The "System.loadLibrary()" method.
In order for the JVM to use the native code, it is necessary to use the static method System.loadLibrary(String libName). That one will load the provided library from the file system into our memory.
Here is a call example:
System.loadLibrary(mylibrary);
It is very important to say that the library's name provided as parameter needs to follow some rules, depending on the platform that the JVM is being executed. For example, lets suppose a library called as "taxcalculator". The following table shows which names should be used for that example.
System Name | Parameter Value | Name of File (without blank spaces) |
---|---|---|
Windows | taxcalculator | taxcalculator .dll |
Solaris | taxcalculator | libtaxcalculator .so |
The provided parameter is converted automatically by JVM like as showed from column "Parameter Value" to "Name File".
Alternatively, we can use the command System.load(D:\\my\\library\\path\\libmylibrary.dll)
to find a library by its fully path.
4. Step by step.
After a simple introduction, let's make a simple example by creating a calculator in Java but making all calculations on C.
4.1. Creating a Java program.
The first step is to create our Java class and declare its methods to be implemented on another language. As said before, we need to load our library, by using the method System.loadLibrary(mylibrary)
.
Note that, the native methods does not have implementations here since it will be done at a C file later. After compile this Java class, there are no errors.
4.2. Generating C header.
Java's compiler allows us to generete our C header automatically, using the command below:
javac Calculator.java -h ../c/
Where:
javac
: Executes the Java compiler.
Calculator.java
: Is the class that needs to be implemented in C.
-h
: Says for compiler where to save the native header file.
../c/
: Is the path where the header is going to be saved.
NOTE: If you are running a version before 10, use the javah
instead of javac -h <path>
After execute that command, a new .h is generated. There, we can see all method's signature that we defined as native using the "native" key word.
4.3. Implementing the methods with native code.
After all these steps, now we need to create the implementation of C code to the Java declared methods.
Let's create a new .c file, there, we included the generated header file and implement a function for all methods, following its signature.
Notice that the methods signature was copy from the generated header, with the difference that all parameters have been changed to have a name that can be referenced in the code.
4.4. Compiling C class.
For compile the C class, I will use the GCC. If you are using Windows (like me), use that step-by-step for stalling it. If you are using Linux, you must already have it installed.
To compile it, we can use the following command (you will have to change it for your case).
gcc -o libcalculator.dll -shared -I"your\java\home\include" -I"your\java\home\include\win32" -I"your\project\c" ./Calculator.c;
Where:
gcc
: Executes the GNU Compiler C.
-o
: Says for compiler where to save the generated file.
libcalculator.dll
: Is the name of the generated file.
-shared
: Says for compiler to create a shared library.
-I"your\java\home\include"
: Is the location of jni.h
, that is used by Calculator.h
.
-I"your\java\home\include\win32"
: Is the location of jni_md.h
for Windows, that is also used by Calculator.h
.
-I"your\project\c"
: Is the location of Calculator.h
, that is used by Calculator.c
.
./Calculator.c
: This is the file we want to compile
All that code needs to be executed in one line. After it, a libcalculator.dll
will be generated.
4.5. Executing our program.
After all these steps, we are able to execute our program. Just do it by using the following command on your/project/java
:
java -Djava.library.path=location/of/libcalculattor Calculator 2 2
NOTE: If you used the System.load
instead of System.loadLibrary
, the -Djava.library.path=location/of/libcalculattor
argument does not need to be provided.
The following image shows the application working:
This is a basic example of how to use JNI. You can see the code by clicking here.
Top comments (0)