JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境。
1、创建java maven项目
创建一个JniDemo类
package com.sumengnan;
public class JniDemo {
static {
//第一种方式:直接写全路径名+文件名
System.load("/Users/sumengnan/CLionProjects/jniSharedLib/libjniSharedLib.dylib");
//第二种方式:只写去掉前缀和后缀的文件名去掉libxxx.dylib
//1、直接放入jdk lib文件夹中:/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/jre/lib
//2、配置java命令vm option参数:-Djava.library.path=/Users/xxx/java/com/sumengnan
//注意:不能用System.setProperty("java.library.path","/Users/xxx/java/com/sumengnan"),因为java.library.path的值只会在jvm启动时读取一次,并且就缓存了,以后便不会改变
//System.loadLibrary("jniSharedLib");
//注:默认的java.library.path为:
///Users/sumengnan/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
}
public native int sayHelloNative();
public static void main(String[] args) {
System.out.println(new JniDemo().sayHelloNative());
}
}
开始生成c头文件:
cd /Users/sumengnan/IdeaProjects/JniDemo/src/main/java(注意:必须是此目录下,别的目录会报错找不到类)
执行javah com.sumengnan.JniDemo (javah来生成C++或C的头文件信息)
注:javah命令在jdk新版本中已经删除(java15)需要使用javac -h
会出现com_sumengnan_JniDemo.h头文件,内容如下:
2、创建c项目
把头文件复制过来(或配置include_directories中头文件位置),并创建一个c文件和CMakeLists.txt
com_sumengnan_JniDemo.c内容如下:
#include "com_sumengnan_JniDemo.h"
#include <stdio.h>
JNIEXPORT jint JNICALL Java_com_sumengnan_JniDemo_sayHelloNative
(JNIEnv *, jobject){
printf("Hello, World!\n");
//jstring无法直接使用,需要转成char *
const char *str=(*env)->GetStringUTFChars(env,string,0);
printf("Hello, World!%s\n",str);
//释放内存
(*env)->ReleaseStringUTFChars(env,string,str);
//其他访问String的方法
// ◆GetStringUTFChars将jstring转换成为UTF-8格式的char*
// ◆GetStringChars将jstring转换成为Unicode格式的char*
// ◆ReleaseStringUTFChars释放指向UTF-8格式的char*的指针
// ◆ReleaseStringChars释放指向Unicode格式的char*的指针
// ◆NewStringUTF创建一个UTF-8格式的String对象
// ◆NewString创建一个Unicode格式的String对象
// ◆GetStringUTFLengt获取UTF-8格式的char*的长度
// ◆GetStringLength获取Unicode格式的char*的长度
return 11;
};
CMakeLists.txt
project(jniSharedLib C)
set(CMAKE_C_STANDARD 99)
#引入此头文件目录,是为了引入jni.h
include_directories("/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/include")
#引入此头文件目录,是为了引入jni_md.h
include_directories("/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home/include/darwin")
add_library(jniSharedLib SHARED com_sumengnan_JniDemo.c)
执行cmke .和make命令即可生成libjniSharedLib.dylib动态链接库文件
3、回到java项目
配置好System.load位置或System.loadLibrary,运行即可得到结果
更多jni开发入门教程参考:JNI 入门介绍(jstring与char*的转换)_丶麦麦鱼的博客-CSDN博客