1. 为什么要研究JNI
线程的interrupt()方法干了什么事?
最终调的是:
private native void interrupt0();
Java研究到native方法之后,看不到方法的实现,Java部分的代码到此结束。native方法是用C/C++语言写的。
Java的底层依赖操作系统,用操作系统提供的函数就要使用C语言,所以要想理解Java的native方法干了啥,就要研究C/C++代码。
总体流程是: Java代码调C/C++写的库,C/C++写的库通过系统调用和操作系统交互。
2. 自己写个native方法,体会一下Java怎么和C++ 交互的
环境: java11 ubuntu20.04
目录结构
3. 创建JniDemo.java
package com.example.java;
public class JniDemo{
public native String getHost();
public native int add(int a, int b);
}
编译
// -h是编译成 .h的头文件 -h 后面加上生成的文件所在的文件夹
javac -h jni JniDemo.java
生成文件
4. 我们需要JNI的头文件
在JDK文件夹的include目录下找到 jni.h 和 linux目录找到jni_md.h复制到项目里面
com_example_java_JniDemo.c是我们创建,内容如下:
#include <stdio.h>
#include "com_example_java_JniDemo.h"
#include "jni.h"
JNIEXPORT jstring JNICALL Java_com_example_java_JniDemo_getHost(JNIEnv *env, jobject jo){
printf("%s\n", "Java_com_example_java_JniDemo_getHost");
// 返回xh-host
return env->NewStringUTF("xh-host");
}
JNIEXPORT jint JNICALL Java_com_example_java_JniDemo_add(JNIEnv *env, jobject jo, jint i1, jint i2){
printf("%s\n", "Java_com_example_java_JniDemo_add");
jint a = i1 + i2;
// 返回 i1+i2, jint就是int
return a;
}
com_example_java_JniDemo.c写好之后,编译成动态库
g++ -fPIC -shared com_example_java_JniDemo.c -o libJniDemo.so -I ./
生成 libJniDemo.so文件
5.测试
Main.java
public class Main {
public static void main(String[] args) throws InterruptedException {
System.load("/home/xh/IdeaProjects/java_base/src/main/java/com/example/java/jni/libJniDemo.so");
JniDemo jniDemo = new JniDemo();
String host = jniDemo.getHost();
System.out.println(host);
int i = jniDemo.add(10, 10);
System.out.println(i);
}
}
打印内容