简述jni

java解决了跨平台

http解决了跨应用

jni解决了java跨语言

姑且,就当它是java跨语言适配器吧。使能像调用操作系统一样,调用别的语言

1. jdk目录说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
├── bin
├── COPYRIGHT
├── db
├── include
├── javafx-src.zip
├── jre
├── lib
├── LICENSE
├── man
├── README.html
├── release
├── src.zip
├── THIRDPARTYLICENSEREADME-JAVAFX.txt
└── THIRDPARTYLICENSEREADME.txt

可见其中有个include目录

1
2
3
4
5
6
7
8
9
10
include/
├── classfile_constants.h
├── jawt.h
├── jdwpTransport.h
├── jni.h
├── jvmticmlr.h
├── jvmti.h
└── linux
├── jawt_md.h
└── jni_md.h

这里的文件,都是.h结尾的c语言头文件

C-language header files that support native-code programming using the Java Native Interface and the Java Virtual Machine Debugger Interface.

解释:c语言的头文件,支持使用jni和jvm debug interface调用本地代码。

2. 开发流程

  1. 定义java native方法

    1. ```java
      public native boolean leaveChannel(long nativeHandle);
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27

      2. javac

      1. `javac *.java -d dest`
      2. 确认文件无误、生成java可执行文件`.class`

      3. javah

      1. `javah -jni *.java`
      2. 根据定义的native方法类,生成`.h`文件

      4. 据h实现c

      1. 完成`.cpp`文件

      5. g++

      1. `g++ xxx.cpp -o xx.so -shared -fPIC -I. -Ixxx -I/usr/java/include -I/usr/java/include/linux xxx.o xxx.o -pthread -lpthread -L`pwd`/../../libs -lrecorder -lrt -I.`
      2. 根据`.cpp` `jvm jni.h` `c其他编译后文件`生成动态链接库`.so`

      6. Java加载动态链接库(.so or .dll)

      1. ```java
      static {
      // System.loadLibrary("recording");
      System.load("xxx/librecording.so");
      }
  2. ……没了

3. 最后的麻烦

java调用c报错

出错信息为c,java接到signal直接崩溃

  • c异常捕获,防止java程序继续执行,引发不可预知异常
    • c中处理
  • c问题排除(对于没玩过c的,太难!!!)
    • Core dump
    • gdb