JNI

动态链接库文件:

  • windows:.dll
  • Linux:.so

Demo:

参考:https://blog.csdn.net/w1992wishes/article/details/80283403

1) 编写 Java 代码:

  • vim DemoJni.java
  • 使用 System.loadLibrary() 从 java.library.path 中加载对应的 dll 或 so 动态链接库
  • 使用 native 关键字,声明对应的 native 方法 ```java package cn.demojie;

public class DemoJni { static { try { // 调用动态链接库 System.loadLibrary(“sayHello”); } catch (Exception e) { System.err.println(“load native library [sayHello] failed.”); } System.out.println(“load native library [sayHello] succeed.”); } // native关键字声明本地方法 public native static String sayHello(String name); public static void main(String[] args) { System.out.println(“Hello “ + sayHello(“Dean.”)); } }

  1. **2) javac 编译:**
  2. ```bash
  3. javac -d . -encoding UTF-8 DemoJni.java
  • -d:直接在指定路径生成对应的包路径

image.png
3) 生成 c 的头文件 .h:

javah -d jnilib -jni cn.demojie.DemoJni
  • -d:指定生成路径

image.png

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class cn_demojie_DemoJni */

#ifndef _Included_cn_demojie_DemoJni
#define _Included_cn_demojie_DemoJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     cn_demojie_DemoJni
 * Method:    sayHello
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_cn_demojie_DemoJni_sayHello
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

4) 进入 jnilib 目录:

cd jnilib

5) 创建 c 源文件:

  • vim sayHello.c
  • 引用刚刚生成的 .h 文件
  • 实现在 .h 文件中声明的函数 ```c

    include “stdio.h”

    include “cn_demojie_DemoJni.h”

JNIEXPORT jstring JNICALL Java_cn_demojie_DemoJni_sayHello (JNIEnv *env, jclass jc, jstring name) { return name; }

**6) 编译 c 文件:**

- JAVA_HOME 需要指向 JDK 的安装路径,如果已经设置了环境变量,则可以自动获取
- export JAVA_HOME=xxxx
```bash
gcc -D_REENTRANT -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -c sayHello.c
  • 头文件中程序依赖了 jni.h,而这个头文件是存在于 JDK 的 include 中的

7) 生成动态链接库文件(.so):

gcc -shared sayHello.o -o libsayHello.so

8) 返回上层目录:

cd ..

9) 运行 java 程序:

java -Djava.library.path=jnilib cn.demojie.DemoJni
  • java.library.path:指定动态链接库文件所在的路径

整个文件:
image.png

之后只需要这个动态链接文件 libsayHello.so,Java 程序就可以调用对应的 native 方法了。

缺点:

JNI 只能调用符合 JVM 规范的动态库,而且对应的 c 程序需要引用 jni.h。对于大多数系统的动态链接库,只能通过编写一个中间的动态链接库进行间接调用,比较麻烦。

JNA

https://www.cnblogs.com/lanxuezaipiao/p/3635556.html