一、JNI:
JNI是java native interface的缩写,翻译过来是java本地开发接口,JNI是一种协议,它允许java和其他语言(主要是C和C++)进行交互,如java调用C和C++代码,同时C和C++代码也可以调用java的代码。
JNI优点:
- 效率上 C/C++是本地语言,比java更高效
- 代码移植,如果之前用C语言开发过模块,可以复用已经存在的c代码
- java反编译比C语言容易,一般加密算法都是用C语言编写,不容易被反编译
二、Java数据类型和JNI数据类型对比
三、Eclipse调用JNI
由于这里先使用java代码和c语言的交互,不涉及到Android层的ndk开发,先使用eclipse走一遍jni的编译和调用流程,而没有使用AS。
-
新建一个java项目,建一个java类,并声明native方法:
package com.will.jni; public class JNITest { //编写native方法 public native static String getStringFromC(); public static void main(String[] args) { } }
-
打开dos命令,定位到项目下的src文件目录,使用javah命令生成.h头文件,执行完javah的命令后刷新项目发现项目下多了个以该类完整类名命名的头文件
-
打开Visual studio,将该头文件加载进来,这时可以看到这个头文件包含了一个"jni.h"的头文件,会提示找不到头文件路径。
-
这个头文件可以在jdk目录下搜索拿到,找到jdk的安装目录,输入jni,得到两个头文件,都拷贝到Visual studio项目中来,然后把com_will_jni_JNITest.h和jni.h的两处头文件引用改为相对路径的引用:
-
新建一个C文件,实现com_will_jni_JNITest.h中声明的函数,这里简单返回一个字符串:
#include "com_will_jni_JNITest.h" //函数实现 JNIEXPORT jstring JNICALL Java_com_will_jni_JNITest_getStringFromC(JNIEnv *env, jclass *jcls){ return (*env)->NewStringUTF(env, "Hellow world jni!"); }
-
生成动态链接库dll文件:
1、点击调试—>配置管理器—>活动解决方案平台—>新增一个x64平台
![]()
2、在右侧项目右击—>项目属性—>配置属性—>配置类型,选择动态库
3、最后点生成—>生成解决方案,即可在项目目录下找到所生成的dll动态库
![]()
7. 将生成的动态库添加到根目录下或者加入到环境变量(一般把动态库放进统一的文件夹下面,加到环境变量中)
8.加入环境变量后重启Eclipse,编写代码加载动态库,并调用native函数:
package com.will.jni;
public class JNITest {
public native static String getStringFromC();
public static void main(String[] args) {
String text = getStringFromC();
System.out.println(text);
}
static {
System.loadLibrary("c_jni");
}
}
9. 运行,输出结果: