JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。
一、java代码
package org.example; public class Main { static { System.load(""); } public static void main(String[] args) { System.out.println(sum(1,2)); } public static native int sum(int a,int b); }
二、生成头文件
javac -help 用法: javac <options> <source files> 其中, 可能的选项包括: @<filename> 从文件读取选项和文件名 -Akey[=value] 传递给注释处理程序的选项 --add-modules <模块>(,<模块>)* 除了初始模块之外要解析的根模块; 如果 <module> 为 ALL-MODULE-PATH, 则为模块路径中的所有模块。 --boot-class-path <path>, -bootclasspath <path> 覆盖引导类文件的位置 --class-path <path>, -classpath <path>, -cp <path> 指定查找用户类文件和注释处理程序的位置 -d <directory> 指定放置生成的类文件的位置 -deprecation 输出使用已过时的 API 的源位置 --enable-preview 启用预览语言功能。要与 -source 或 --release 一起使用。 -encoding <encoding> 指定源文件使用的字符编码 -endorseddirs <dirs> 覆盖签名的标准路径的位置 -extdirs <dirs> 覆盖所安装扩展的位置 -g 生成所有调试信息 -g:{lines,vars,source} 只生成某些调试信息 -g:none 不生成任何调试信息 -h <directory> 指定放置生成的本机标头文件的位置 --help, -help, -? 输出此帮助消息 --help-extra, -X 输出额外选项的帮助 -implicit:{none,class} 指定是否为隐式引用文件生成类文件 -J<flag> 直接将 <标记> 传递给运行时系统 --limit-modules <模块>(,<模块>)* 限制可观察模块的领域 --module <module-name>, -m <module-name> 只编译指定的模块, 请检查时间戳 --module-path <path>, -p <path> 指定查找应用程序模块的位置 --module-source-path <module-source-path> --release <release> 针对特定 VM 版本进行编译。支持的目标: 6, 7, 8, 9, 10, 11 -s <directory> 指定放置生成的源文件的位置 -source <release> 提供与指定发行版的源兼容性 --source-path <path>, -sourcepath <path> 指定查找输入源文件的位置 --system <jdk>|none 覆盖系统模块位置 -target <release> 生成特定 VM 版本的类文件 --upgrade-module-path <path> 覆盖可升级模块位置 -verbose 输出有关编译器正在执行的操作的消息 --version, -version 版本信息 -Werror 出现警告时终止编译
javac -encoding utf8 -h ./ Main.java
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_example_Main */ #ifndef _Included_org_example_Main #define _Included_org_example_Main #ifdef __cplusplus extern "C" { #endif /* * Class: org_example_Main * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_org_example_Main_sum (JNIEnv *, jclass, jint, jint); #ifdef __cplusplus } #endif #endif
jni与java类型的对应关系
三、生成DLL文件
使用Clion新建c++库文件
CMakeLists.txt增加引入
include_directories(D:\\ProgramFiles\\Java\\jdk-11.0.6\\include) include_directories(D:\\ProgramFiles\\Java\\jdk-11.0.6\\include\\win32)
其中0712_01为新建项目的名称,不必修改。
将生成的头文件org_example_Main.h复制到根目录,复制一份头文件修改后缀为cpp删除所有内容。
编辑org_example_Main.cpp
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> #include "org_example_Main.h" /* * Class: org_example_Main * Method: sum * Signature: (II)I */ JNIEXPORT jint JNICALL Java_org_example_Main_sum (JNIEnv *, jclass, jint a, jint b){ return a+b; }
将org_example_Main.cpp org_example_Main.h加入到CMakeLists.txt
add_library(0712_01 SHARED org_example_Main.cpp org_example_Main.h)
构建程序
查看cmake-build-debug文件夹下的dll文件
四、加载dll文件运行程序
修改Main.java,加载DLL文件
package org.example; public class Main { static { System.load("F:\\myCode\\java\\jvm\\0710_demo02\\demo02\\src\\main\\java\\org\\example\\lib0712_01.dll"); } public static void main(String[] args) { System.out.println(sum(10,20)); } public static native int sum(int a,int b); }