JNI入门引导

作者:张维,引用请注明来源


1,什么是JNI

JNI=Java Native Interface = java 本地接口

这里的关键是“本地”这两个字,什么是“本地”?

本地就是操作系统可以直接执行的代码,这是相对"JAVA代码"而言的,JAVA在这个时候可以被称为“外地代码”

要知道,java编译出来的代码,操作系统无法执行,要经过JAVA虚拟机的实时“翻译”才能交给CPU去处理,

一般来说,本地代码是C|C++代码编译出来的。

因此,jni,总体上的意思,就是,给一个接口,让java这个外地人,可以调用本地的代码,或者让本地代码调用java代码。

 

2,什么时候需要jni

当你做一个java项目的时候,偶尔发现,有一个工作是JAVA无法做到的,或者,不容易做,不适合做,需要用到C等语言。

这个时候,你会把难题交给C,然后,让JAVA去调用C编译出来的东西。

常常在几个场景下用到JNI

1)访问硬件资源,一般是驱动之类,

2)特殊的算法,必须用C这一类语言来处理的。

3)已经有一个模块用C做好了,如果再用JAVA实现是浪费时间。

4)遗留代码,或者是开发团队的历史原因。

 

3,JNI的基本工作流程

设计JNI的时候,是先JAVA再C

主要有5步,1,设计JAVA类,2,编译JAVA类,3,生成头文件,4,创建C++动态库,5,在JAVA中载入C库

你先考虑好哪些事情要通过JNI来做的,把这些事情归纳好来,设计成一个JAVA类

在JAVA类中,把要做的事声明成一个一个的方法。

这时候,方法只有声明,没有实现,同时,还多了一个native关键字。

如:

package ty.house.mcu;

public class TyMcuJni {
	public static native int read(byte[] byArr);
	public static native int write(byte[] byArr);
	public static native int ioctl(int iCommand, byte[] byArr);
}

编译这个类。

在编译后产生字节码的目录下,调用 javah命令生成头文件

javah ty.house.mcu.TyMcuJni

 于是就会生成一个.h的C头文件。

ty_house_mcu_TyMcuJni.h

然后,新建一个C++动态库工程,实现头文件里面的函数,生成一个动态库文件,WINDOWS是DLL,LINUX是SO

生成动态库之后,JAVA中就可以调用这个库了

一般在项目开始运行,或是模块开始载入时使用System.loadLibrary(动态库的名称);

如果要调用那个JNI方法,就像调用变通的JAVA方法一样

byte[] dataHolder = new byte[20];

TyMcuJni.read(dataHolder);

刚才说的是JAVA调用 C++,当然JNI的另一个方面就是C++调用JAVA。

C++调用JAVA,主要就是通过字节码的搜索,找到JAVA类,找到方法,再调用。

简要的列一段代码

	clsStatic = (pEnv)->FindClass("ty/house/mcu/TyMcuNative");
	methodId = (pEnv)->GetStaticMethodID(clsStatic,"test","([BI)I");
	iJavaRet = (pEnv)->CallStaticIntMethod(clsStatic,methodId,jbTest,65535);

基本工作流程暂时就这么简单的带过了。以后会有专门的文章更深入的讲JNI。

 

4,JNI的几个关键点

1)了解JAVA类型与C++类型的对应表。
如jint对应着java的int和c++的int.
这是简单的,难的是复杂的对象的对应和数组的对应。

2)java对象与c++对象的转换。
如果是原生类型,像int之类的转换,都简单,甚至一个(int)就把jint变成int了。
但是数组的转换就难多了,
比如,JAVA传一个byte[]给c++,变成了jbytearray,C++必须要转成自己的byte[]才能处理这个字节数组。
jni,顾名思义,最后一个I,是interface。那就是接口。
因此,这个技术最关键的就是转换,转接。

3)在C++中对JAVA对象的内存管理
难免会生成JAVA对象,如果不及时的回收,就造成内存泄漏了。

4)一定要记得看JDK目录下的JNI的头文件
jni.h,这个文件不大不小,里面有JNI中各个基本类型和函数。
了解一下还是有必要的。

 

5,正确的采用JNI

如果你真的有需要,可以放心的采用它

JNI目前已经是一个十分成熟,应用很广泛的技术。

JAVA虚拟机的实现,本身就极大的利用了JNI。

但是,不能为了用它而用它,

如果你的工作能在JAVA端处理好,尽量不要放在C里面做,

如果你本意是觉得C的效率高,那我要告诉你JNI调用本来可能是损失一定的性能,要权衡好。

而且,有的C代码写得不好,还不如直接用JAVA,

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值