JNI 开发一般流程
JNI(Java Native Interface),Java 和C/C++ 相互调用的一套API,教程相对简单,入门系列。
一般流程
- 编写native方法
- javah命令,生成.h头文件
- 复制.h头文件到cpp工程中,复制JDK里面的jni.h和jni_md.h文件到工程中
- 实现.h头文件中声明的函数
- 生成dll文件给Java调用
- 配置动态库给环境变量
1.编写native方法
1 | public class JniTest{ |
2.生成头文件
使用javah命令生成.h头文件,头文件代码自动生成。规则:(C的函数名称:Java_完整类名_函数名)
1 | /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_jni_JniTest */ |
####生成头文件可能遇到的问题
使用javah命令提示找不到类文件
我的工作路径是C:\Users\Administarator\Desktop\JniStudy\java_jni,下面就是src和bin,不要直接进入src目录使用javah命令,正确的命令行应该是:
1
javah -classpath bin -d jni com.jni.JniTest
3.复制头文件
准备头文件,头文件有刚刚生成的.h文件以及拷贝以下路径的.h头文件。路径分别为:
1 | JDK路径\include\win32\jni_md.h |
然后在Visual Studio使用添加项来添加头文件,如果还有报错,
将生成的头文件.h的#include <jni.h>改为#include “jni.h”
4.实现.h头文件中的函数
1 |
|
5.生成dll动态库给java调用
右键Visual studio项目 -> 属性 -> 配置类型(动态库dll),然后生成解决方案。
为什么是dll呢,windows下,使用dll,如果是在android下,就要使用.so。dll动态库生成了之后,要在环境变量中配置动态库的路径,不然eclipse找不到动态库,配置了之后,要重启eclipse。
6.加载动态库
1 | public class JniTest{ |
最后当然是输出 Hello JNI!
JNIEnv
1 | JNIEXPORT jstring JNICALL Java_com_jni_JniTest_getStringFromC |
1 | struct JNINativeInterface_; struct JNIEnv_; typedef JNIEnv_ JNIEnv; typedef const struct JNINativeInterface_ *JNIEnv; |
在C和C++中env的使用方式不相同,并且他们的定义也不相同。在C中,JNIEnv是一个结构体指针别名,env是一个二级指针;在C++中,JNIEnv是一个结构体别名,env是一个一级指针。函数执行过程中,需要JNIEnv,C++为什么没有传入,因为有this可以拿到。C++只是对C的那一套做了一层封装。