浅谈Java的本地方法实现JNI

Posted fusiji

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈Java的本地方法实现JNI相关的知识,希望对你有一定的参考价值。

最近做了一个数据结构课上迷宫求解的问题,要求在栈结构上最好能带一个图形界面,将找到的迷宫路径展示出来。原本打算连图形界面一起用C语言写,但是C语言的图形界面如果不调用操作系统的图形库真的很难看,所以选择了Java写图形界面,C语言写算法的这样一个混合编程的方案。这里不对Java图形界面的具体实现和C的算法做解释,只介绍Java和C的“连接部分”。

 

使用本地方法的前提

虽然现在Java的执行效率的确得到了很大的提升,但是一旦遇到大量计算操作时,还是不如C语言执行快。这种情况下,我们可以考虑将关键的算法部分交给C语言去处理,而其余的部分由Java处理。

Java部分

Java中应对C语言中预期的函数进行声明,这里规定使用native关键字,如:

public static native void something();

采用这种native声明的方式,告知JVM这个方法的定义和具体实现在外部完成,JVM只负责唤醒这个C函数;之后编译这个文件。而在所有操作都完成后,还要向文件中添加static标记的域,如:

static System.loadLibrary(“Something”);

然后再重新编译。前后总共编译两次。

C部分

至于C部分,因为是要让JVM调用C程序,所以首先要保证JVM能识别C程序——又因为JVM能识别的是Java格式,所以你的C代码要按照JVM能识别的样式编写。

这里我们用到了javah这个程序,这个程序帮助我们按照之前第一次编译好的本地方法类文件自动生成JVM期许样式的包含C函数声明的C头文件,之后我们要从这个头文件中复制函数声明到自己的C源文件中,作为C程序的入口(相当于正常C代码中的main函数)。

之后把这个所谓的“main”函数处理好后,其余的其他函数如果C程序不涉及与Java部分参数交互的话,就完全按照C语言标准编写。

 

连接操作

对于Java来讲,其运行在JVM上以实现跨平台能力。但对于C语言来说,却是紧紧依赖操作系统的。所以Java和C混合编程的结果就是受C语言的影响,Java的跨平台能力受到限制——这也是为什么JVM自身是有平台局限性的,而运行在JVM上的纯Java应用是跨平台的。既然收到操作系统的限制,也就不得不将Windows和Linux分开。

对于Linux,在得到头文件后,使用:

gcc -fPIC -I jdkPath/include -I jdkPath/include/linux -shared -o libname.so name.c

这条命令进行编译。之后将.so文件所在路径添加到库路径中。

而对于Windows,得到头文件后,虽然也可以通过cl(微软编译器)编译处理,但是用惯了图形IDE的人可能对命令行界面并不感冒。所以这里介绍使用图形IDE生成动态库文件的方法。

1)首先需要将Java安装目录下jdk/include中的jni.h和jdk/include/win32中的jni_md.h复制到相应C编辑器目录下的include目录中。include目录在Visual Studio中能直接找到,在Dev C++中在MinGW64这个子目录中。

2)之后用该编辑器建立一个DLL项目,在这个项目中编译C文件生成name.dll,将该dll复制到Eclipse(如果是Eclipse)相应Java项目的文件夹下即可;若不是,可复制到jdk/bin或jre/bin下。

 

但不管是Windows还是Linux,之后都要再回到Java项目相应本地类源文件,添加之前所说的static标记域,其中的Something是你的dll文件的名字。然后编译Java代码,运行。

 

以上是关于浅谈Java的本地方法实现JNI的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Java中的hashcode方法

浅谈Java中的hashcode方法

浅谈Java中的hashCode方法

浅谈Java中的hashcode方法

浅谈Java中的hashcode方法

浅谈Java中的hashcode方法