澳门新葡萄京官网注册 3

澳门新葡萄京官网注册Java 本地接口 JNI 使用详解

对于java程序员来讲,java语言的低价和亮点,笔者想不要本身说了,大家当然会揭露相当多风流洒脱套套的。但就算大家作为java程序猿,但大家必须要承认java语言也可以有局地它自个儿的弱点。举个例子在品质、和底部打交道方面都有它的弱项。所以java就提供了风流倜傥部分地点接口,他根本的功用正是提供八个专门的学问的诀要让java程序通过虚构机与原生代码举行人机联作,那也正是大家平时常说的java本地接口(JNI——java native Interface)。它使得在 Java 虚构机(VM卡塔尔国 内部运维的Java 代码能够与用其余编制程序语言(如 C、C++ 和汇编语言)编写的应用程序和库开展互操作。JNI 最器重的补益是它未有对底层 Java 设想机的兑现施加任何约束。由此,Java设想机厂商能够在不影响设想机别的一些的情况下增多对JNI 的支撑。程序猿只需编写风流倜傥种版本的地面应用程序或库,就可以预知与有着援助JNI 的Java 设想机协作职业。大家来看一下为啥要与原生代码举办交互作用:

意气风发:提升应用程序质量。我们知道java对于c/c++、汇编语言来讲,显得比较“高端”。其实这里的高端便是简化了技术员的行事。相当多底部的东西都让java虚构机做了。但终究相对于间接访问底层来说,java多了一步虚构机的历程,所以在质量上比着这一个原生语言稍稍有一点慢。

二:完结部分与底层相关的效应。Java平台提供的正规化类库,还大概有强盛的API,固然能幸不辱命大多数意义。但有个别和底部硬件打交道的意义在java API提供的类库中仍然回天无力做到。

三:与已有个别使用原生代码编写的前后相继进行集成。在于操作系统上由c恐怕c++等原生语言编写的软件实行归并的时候,能够用JNI。

JNI 接口函数和指针

阳台相关代码是透过调用 JNI 函数来访谈Java 设想机成效的。JNI 函数可因此接口指针来拿到。接口指针是指针的指针,它指向一个指南针数组,而指针数组中的各种成分又针对叁个接口函数。每一种接口函数都地处数组的某部预约偏移量中。下图表达了接口指针的团队构造。

澳门新葡萄京官网注册 1

JNI 接口的集体相符于C++ 虚构函数表或COM 接口。使用接口表而不利用硬性编入的函数表的补益是使JNI 名字空间与平台相关代码分开。虚构机能够比较轻易地提供多少个本子的JNI 函数表。比方,虚构机可补助以下三个JNI 函数表:

1)二个表对违规参数进行完美检讨,适用于调节和测验程序;

2)另叁个表只进行 JNI 规范所供给的蝇头程度的自己商议,因而功效较高。

JNI 接口指针只在脚下线程中有效。因而,当地方法不可能将接口指针从三个线程传递到另二个线程中。完毕 JNI 的虚构机可将地点线程的数额分配和积攒在 JNI 接口指针所针没错区域中。

地面方法将JNI 接口指针充当参数来选取。虚构机在从相仿的 Java 线程中对本土方法开展频仍调用时,保障传递给该地点方法的接口指针是千篇风华正茂律的。不过,叁个地点方法可被不相同的 Java 线程所调用,由此能够担当不一样的 JNI 接口指针。

澳门新葡萄京官网注册 2

1)编写Java类代码

当中,需求JNI达成的法子应该用native关键字证明,在那类中,用System.loadLibrary(卡塔尔方法加载须求的动态链接库,关键代码如下:

//Compute.java
public class Compute{
    public native double sqrt(double  params);
    static{
        //调用动态链接库
        System.loadLibrary("compute");
    }
}

2State of Qatar编写翻译成字节代码

在那几个进程中,由于使用了native关键字表明,Java编写翻译器会忽视未有代码体的JNI方法有个别。

3卡塔尔(قطر‎生成相关JNI方法的头文件

本条进程的落实经常是通过使用jlavah-jni  * class生成的(-jni能够轻易),也能够手工业生成该公文;可是出于 Java 虚构机是依靠早晚的命名标准达成对JNI方法的调用,所以手工业编写制定头文件须要非常小心。

上述文件发出的头文件部分代码如下:

//Compute.h
extern“C”{
JNIEXPORT jdoubleJNICALL Java_Compute_comp(JNI-Env *, jobject, jdoubleArray);

JNI函数名称分为三有的:首先是Java关键字,供Java虚构机识别;然后是调用者类名称(全约束的类名,在那之中用下划线取代名称分隔符卡塔尔国;最后是对应的点子名称,各段名称之间用下划线分割。

JNI函数的参数也由三部分构成:首先是JNIEnv *,是多少个照准JNI运营条件的指针;第四个参数随当地点法是静态依然非静态而有所分化生机勃勃大器晚成非静态本地方法的第4个参数是对指标的援用,而静态本地点法的第二个参数是对其Java类的援引;其他的参数对应平常Java方法的参数,参数类型供给依据早晚准绳进行映射。

4卡塔尔国编写相应措施的实今世码

在编码进程中,供给注意变量的尺寸难点,举例Java的整型变量长度为叁12个人,而C语言为16个人,所以要细心核查变量类型映射表,幸免在传值进程中冒出难点。

5卡塔尔国将JNI实今世码编写翻译成动态链接库

编写翻译进程是采纳C/C++编写翻译器完毕的,在windows平台上,编写翻译和三回九转的结果是动态链接库DLL文件。当要动用生成的动态链接库时,调用者类中必要显式调用该链接库dll文件。
通过上述管理,基本上完结了七个包涵本地化方法的Java类的费用。

附录:将Jav类型映射到本地C 类型

澳门新葡萄京官网注册 3

为了使用方便,特提供以下定义。

#define JNI_FALSE  0

#define JNI_TRUE   1

jsize 整数类型用于描述主要指数和尺寸:

typedef jint jsize;

故障排除

当使用 JNI 从Java 程序访问本机代码时,您会遇见重重标题。您会遇上的两个最广泛的不当是:

1)十分小概找到动态链接。它所发生的错误音信是:java.lang.UnsatisfiedLinkError。那平时指不可能找到分享库,大概不或者找到共享库内一定的本机方法。

2)不可能找到分享库文件。当用 System.loadLibrary(String libname卡塔尔(قطر‎ 方法(参数是文本名)装入库文件时,请保管文件名拼写准确以至从未点名扩充名。还会有,确定保证库文件的岗位在类路线中,进而保障 JVM 能够访谈该库文件。

3)不能找到具备钦命表达的章程。确认保证您的 C/C++ 函数达成全体与头文件中的函数表达相仿的辨证。

结束语

从 Java 调用 C 或 C++ 本机代码(即使不轻便)是 Java 平台北豆蔻梢头种能够集成的法力。尽管 JNI 扶持 C 和 C++,但 C++ 接口更鲜圣元些同一时间普通比 C 接口更可取。正如你已经阅览的,调用 C 或 C++ 本机代码需求予以函数特殊的名号,并创办分享库文件。当使用现成代码库时,改良代码常常是不可取的。要制止那点,在C++ 中,平常创造代理代码或代理类,它们有特意的 JNI 所需的命名函数。然后,那一个函数能够调用底层库函数,那个库函数的认证和兑现保证不改变。

发表评论

电子邮件地址不会被公开。 必填项已用*标注