JNI 介绍
先说JNI(Java Native Interface)吧,有过不同语言间通信经历的一般都知道,它允许Java代码和其他语言(尤其C/C++)写的代码进行交互,只要遵守调用约定即可。首先看下JNI调用C/C++的过程,注意写程序时自下而上,调用时自上而下。
可 见步骤非常的多,很麻烦,使用 JNI 调用 .dll/.so 共享库都能体会到这个痛苦的过程。如果已有一个编译好的 .dll/.so 文件,如果使用 JNI 技术调用,我们首先需要使用 C 语言另外写一个 .dll/.so 共享库,使用 SUN 规定的数据结构替代 C 语言的数据结构,调用已有的 dll/so 中公布的函 数。然后再在 Java 中载入这个库 dll/so,最后编写 Java native 函数作为链接库中函数的代理。经过这些繁琐的步骤才能在 Java 中调用 本地代码。因此,很少有 Java 程序员愿意编写调用 dll/.so 库中原生函数的 java 程序。这也使 Java 语言在客户端上乏善可陈,可以说 JNI 是 Java的一大弱点!
JNI 入门案例
JNI 编程总体分为 5 个步骤:
- 编写 java 类;
- 利用 javah(在 %JAVA_HOME%/bin 文件夹下),生成 .h 头文件
- 实现生成的 .h 头文件里的方法;
- 生成 dll 动态链接库;
- java 调用测试;
1.编写 java 类
新建一个空项目
public class JNIDemo {
// 定义 native 方法
public static native void getLine(String prompt);
public static void main(String[] args) {
// 加载库文件(不用带后缀名)
System.loadLibrary("JNIDemo");
// 调用方法
JNIDemo.getLine("This is Java message!!!");
}
}
2.利用 javah 生成 .h 头文件
在src(Idea)/bin(Eclipse) 目录下执行
javah -classpath . -jni 全类名
,这样就会在 src/bin 目录下生成一个 .h 的头文件,保存好后面用到;
3.实现 .h 头文件里的方法并生成 dll 文件
-
第一步,新建项目
-
第二步,新建类
编写代码
-
第三步,右击头文件,添加现有项
把之前的 .h 文件导入进来,还有 %JAVA_HOME%/include/jni.h 和 %JAVA_HOME%/include/x32/jni_md.h 也一起导进来;
然后编辑我们创建的 .h 文件,将#include <jni.h>
改为#include "jni.h"
;
4.第四步,右击解决方案 -> 属性 -> 配置属性
然后选中解决方案,将杂项中的活动配置也改为 x64(看你的 JDK 是多少位的,如果是 32 的,就改为 32 的[java -version 查看])
- 最后右击解决方案 -> 生成解决方案。在当前路径就生成了 x64/x32 目录,下面就有一个 dll 文件
4.java 调用测试
package com.topsec.test;
/**
* Description: JNIDemo
* Created by dell on 2022/1/4 13:27
*/
public class JNIDemo {
static {
System.load("C:\\Users\\dell\\Desktop\\JNIDemo.dll");
}
// 或
static {
// 需要在项目的 Library 中加载 dll 文件;
System.loadLibrary("JNIDemo");
}
public static native void getLine(String prompt);
public static void main(String[] args) {
JNIDemo.getLine("This is Java message!!!");
}
}