- 创建
.java文件 - 增加
native的相关方法 - 使用
javac生成.java文件的class文件和对应的.h头文件javac -h jni_target_dictory jni.java filecase:
javac -h src/autorun/jvm/jni/ src/autorun/jvm/jni/HelloJni.java - 如果使用clion类似工具开发时则需要在
CMakeLists.txt增加生成好的.h文件方便编译
在
CMakeLists.txt的add_executable步骤中增加对应的.h文件。使IDE找到对应的头文件
- 编译时建议直接通过 include 参数引用
$JAVA_HOME/include以及对应平台目录, 例如 Linux 的$JAVA_HOME/include/linux、macOS 的$JAVA_HOME/include/darwin。不建议把 JDK 自带的jni.h、jni_md.h拷贝到工程中维护。 - 编写
.h头文件的实现。
- 首先如果是
static的native方法, 参数名为jclass. 换句话说jclass是拿到的被JNIHandles::make_local(klass)包装过的klass实例。 更准确地说, JNI 层拿到的是声明该 native 方法的java.lang.Class对象的 JNI 引用。HotSpot 内部会通过 mirror 和 Klass 建立关联, 但在 JNI API 视角下不应直接把jclass理解为 Klass 实例。
- 编译
so文件. 如果是c语言也就是.c文件编译时使用gcc -fPIC -shared sourceFile -o libxxx.so如果是c++ 则将上面命令中的gcc替换为g++即可。macOS 生成.dylib时可使用-dynamiclib。
- 编写java代码,加载时可以使用
System.load(file)或者使用System.loadLibrary(libname)加载对应的本地包
System.load(file) 和 System.loadLibrary(libname) 差别。参考如下链接
Java System.load() 与 System.loadLibrary() 区别解析