说明
由于一些涉及到设备或底层操作的类库,大多是C或C++语言编写的,对于Java Web开发者,在涉及到相应的项目中,不可能再去将相应的类库用Java重写。这时,就需要通过Java代码去调用C/C++的类库来完成工作。
操作环境:
- JDK 1.8.0_45
- Eclipse
- Visual Studio 2013
注意: demo中的文件路径需要加以注意!!!
演示实现
整体目标
通过Java调用C++代码编写的 *.dll 类库中封装的方法,本 Demo 中包含两个方法,一个是输出文本信息,无返回值;一个计算并返回两个整数之和。
编写Java接口
package com.daniel;
/**
* JNI 测试类 JNI_Test.java
* @author PeiXQ
*/
public class JNI_Test {
/**
* 打印文本
* @param mess
*/
public native void sendMess(String mess);
/**
* 计算数值和
* @param a
* @param b
* @return
*/
public native int plusNum(int a,int b);
}
编写完成后,生成 .class 文件。
生成 *.h 头文件
进入 cmd
命令行,使用上一步生成的 .class 文件,利用 jdk 的 javah 命令生成 *.h 头文件。
# javah
# -classpath :E:\JNI_Java_Pro\bin 为.class 文件所在的根路径
# .class 文件的完整路径为E:\JNI_Java_Pro\bin\com\daniel\JNI_Test.class
# -d : E:\tmp\JNI 输出 *.h 头文件的路径
# -jni : 生成JNI样式的包头文件,可以理解成 *.class 文件的 包路径+类名
#
# 此处比较诡异的是,-classpath 必须得是*.class 的包路径文件的上一级;
# -jni 必须是*.class 文件的 包路径+类名,否则会报错。
javah -classpath E:\JNI_Java_Pro\bin -d E:\tmp\JNI -jni com.daniel.JNI_Test
编写C++代码
创建一个C++项目
设置应用类型为 dll
将 jdk 目录下的 jni.h 、 jni_md.h 以及之前生成的 com_daniel_JNI_Test.h 放入项目根路径下的 include 文件夹 (需自己创建文件夹)
添加项目包含目录,将上一步创建的 include 文件夹包含进项目。
创建 test_jni.cpp 文件,并编写 c++ 代码实现,其中的方法头,可以从 com_daniel_JNI_Test.h 中拷贝。
生成C++dll
运行C++项目的生成按钮,并在生成路径下找到生成的 dll 文件(本文为 jni_gen.dll)。
Java调用C++ dll
将生成的 *.dll 添加到Java项目的 Native Library 中,如使用Eclipse,如下图:
修改最初的 JNI_Test.java 的代码,调用 dll 中的方法,可看到最下方输出的执行结果。