由 HelloWorld.cpp 生成 HelloWorld.o 的命令
有 HelloWorld.o 生成 libhelloworld.jnilib 的命令
获取作为 java.library.path 的几个目录的路径
还可以在执行时将 jnilib 所在路径的作为参数传递进去(假如 HelloWorld.jnilib 在桌面上)
This tutorial combines a few key ideas to getting started with a Hello World program using the Java Native Interface (JNI) on Mac OSX. JNI allows Java code to utilize C++ code (i.e., native code).
This technology is very important if you want to do any computationally intensive operations (games, video processing, audio processing, etc) in mobile (Android) apps or your everyday Java applications.
The important point to this article is that most tutorials only talk about compilation for Windows and Solaris machines — I will focus exclusively on OSX. Knowing these subtleties can save you a lot of time and headaches!
Creating the Java Class
Let’s start by creating a very simple Hello World program!
In a file HelloWorld.java
1 2 3 4 5 6 7 8 9 10
The above code details a simple Java class that has a very important native method print(). The fact that this method is native signifies that it should be implemented in C++. We’ll get to that implementation in a bit.
The static section gets executed first, which expects to load a JNI shared or dynamic library known as HelloWorld.
Compiling the Java Class
Compiling the newly created HelloWorld class involves opening up the terminal and issuing the command:
We use the javac command to generate the class file that is needed to generate the appropriate JNI C++ classes. You can’t skip the generation of the class file!
To create the JNI C++ files, you can just type the following command into the terminal:
The above command will generate the following header file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
This file contains a lot of seemingly obscure boiler-plate specific to JNI. The part we care about is the definition of the print() function that was declared to be native in the HelloWorld.java file.
By convention, native functions will be named “Java” followed by the class name “HelloWorld” and the function name “print”. Thus, we obtain the native function: Java_HelloWorld_print().
Let’s write an implementation file to define the behavior of the Java_HelloWorld_print() function.
1 2 3 4 5 6 7 8 9 10 11
The implementation of the native function simply prints out a literal string.
Compiling the C++ Code
To include the native code in the compilation of the Java program, we need to compile our native C++ code into a dynamic library. On OSX, JNI shared/dynamic libraries have the extension .jnilib. This is a huge difference from the extensions on Windows and Solaris machines: .dll and .so, respectively.
Before we get to the command, there’s a big problem: your compiler (g++) will need to know the location of the jni.h library. You don’t get this linking for free, so you have to specify the location of the header file within the compilation command.
The locations of the the jni.h library that need to be included are:
Unfortunately, leaving off either of these results in the compiler error:
HelloWorld.cpp:1:17: error: jni.h: No such file or directory
In your terminal, issue the command (all part of a single command):
Notice that we include the -c option to generate the object file for our native code: HelloWorld.o. We also include the implementation file for our native class: HelloWorld.cpp.
The final step for compiling the native source is to issue the command:
This command uses the dynamiclib option to specify that the compiler shouldn’t produce a standard executable, but should produce a library. The -o option is used to name the library with the appropriate extension: libhelloworld.jnilib. We also include the object file generated in the previous step.
The result of this process is the compiled library libhelloworld.jnilib.
Compiling the Native Library and Java Program
The final piece to this painstaking puzzle is to connect all of the pieces! We’re going to finally compile our Java program which will look for the jnilib library containing our compiled native code.
In your terminal, issue the following command:
This will compile and run our HelloWorld program and display the output:
Oh JNI, how cumbersome you are!
One final note
If you see the error:
1 2 3 4 5
Then you’ve mistakenly used a different shared/dynamic library extension than the necessary .jnilib! This is the root of all evil in this exercise!
This tutorial is based on the JNI tutorial provided by Sun.