JNI系列(一)JNI简介

一、什么是JNI?

 

看下百度百科怎么说的:

JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境。

 

简单点来说就是:

1.JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C和C++)
2.通过JNI可以实现java和本地代码之间相互调用
3.jni可以看做是翻译 实际上就是一套协议

 

 

二、为什么要用JNI?

 

在java程序中,我们可以通过JNI实现一些用java语言不便实现的功能,如下:

1)标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的(只能由其他语言编写)。

2)你希望使用一些已经有的类库或者应用程序,而他们并非用java语言编写的。

3)程序的某些部分对速度要求比较苛刻,你选择用汇编或者c语言来实现并在java语言中调用他们。

4)为了应用的安全性,会将一些复杂的逻辑和算法通过本地代码(C或C++)来实现,本地代码比字节码难以**。

 

三、怎么用JNI?

 

JNI开发流程主要分为以下6步:

1)、编写声明了native方法的Java类
2)、将Java源代码编译成class字节码文件
3)、用javah -jni命令生成.h头文件(javah是jdk自带的一个命令,-jni参数表示将class中用native声明的函数生成jni规则的函数)
4)、用本地代码实现.h头文件中的函数
5)、将本地代码编译成动态库(windows:*.dll,linux/unix:*.so,mac os x:*.jnilib)
6)、拷贝动态库至 java.library.path 本地库搜索目录下,并运行Java程序

 

四、什么是JNA?

 

JNA全称Java Native Access,是一个建立在经典的JNI技术之上的Java开源框架(https://github.com/twall/jna)。JNA提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

 

五、JNI与JNA

 

JNI优点:效率高

JNA调用C/C++函数效率高

 

JNI缺点:繁琐

我们知道,使用JNI调用.dll/.so共享类库是非常非常麻烦和痛苦的。

如果有一个现有的.dll/.so文件,如果使用JNI技术调用,我们首先需要另外使用C语言写一个.dll/.so共享库,使用SUN规定的数据结构替代C语言的数据结构,调用已有的  dll/so中公布的函数。

然后再在Java中载入这个适配器dll/so,再编写Java   native函数作为dll中函数的代理。

经过2个繁琐的步骤才能在Java中调用本地代码。

因此,很少有Java程序员愿意编写调用dll/.so库中的原生函数的java程序。这也使Java语言在客户端上乏善可陈。可以说JNI是Java的一大弱点!
 

JNA优点:简单

JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll,Android的so)而不需要编写任何Native/JNI代码。开发人员只要在一个Java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

 

JNA缺点:性能损失

使用JNA技术比使用JNI技术调用动态链接库会有些微的性能损失。可能速度会降低十几倍