今晚北京的风很大,大到路边的ofo都一路向我贴服膜拜。好的吧,这是我今晚的心情,hhh,当我的Java程序抛出了C++算法的运算结果,一下子,我就跳了起来。如同年幼的时候,蹦蹦跳跳的跑出实验室大笑了几声,连夸了自己几句,“真厉害!好棒!这都能做出来”这样的话语,平复了下自己激动的心情,抹去脸上的笑容,深吸了一口气,转身走向了实验室。
因为这个帖子是给以后年老色衰的我写的,反正也不会有人看,hhh,我就随意的写点啦。
首先,我们得正儿八经的介绍一下JNI编程。JNI其实是Java Native Interface的简称,也就是java本地接口。它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++)。
本场长在使用过程中,主要感受是JNI通过构建一个Native的函数,创建一个本地接口,其他语言(如C++)可以把这个接口文件作为头文件,在程序运行过程中调用。那么...为什么要需要JNI这种东西呢?我们知道Java是一种平台无关性的语言,平台对于上层的java代码来说是透明的,所以在多数时间我们是不需要JNI的,但是假如你遇到了如下的三种情况之一呢?
1. 你的Java代码,需要得到一个文件的属性。但是你找遍了JDK帮助文档也找不到相关的API。
2. 在本地还有一个别的系统,不过他不是Java语言实现的,这个时候你的老板要求你把两套系统整合到一起。
3. 你的Java代码中需要用到某种算法,不过算法是用C实现并封装在动态链接库文件(DLL)当中的。
对于上述的三种情况,如果没有JNI的话,那就会变得异常棘手了。就算找到解决方案了,也是费时费力。其实说到底还是会增加开发和维护的成本。
本场长遇到的就是第三种情况,手里头有两套算法,一套是用java写的,一套是用C++写的。因为java所用到的库很复杂,本人又是java萌新,所以如何搭建一套完整的JAVA-C++通信是十分重要的。
一、运行环境
本场长是在win10环境下的Eclipse对整体算法框架进行整理。其中C++是采用Eclipse CDT。Eclipse作为开源的IDE,可以用来高效开发Java、C++、C等程序。但是由于场长不适应Eclipse CDT的编译规则,特别是头文件无处安放,所以,在C++层面是先用VS2015进行整理,然后再导入进Eclipse CDT的界面中。主要界面如下:
二、Eclipse CDT
既然说到Eclipse CDT,那我们就先梳理一下它吧。Eclipse作为Java开发的主要IDE,它也可以兼容开发C++,C等语言。但是这需要一个插件的帮助,那就是MinGW。
MinGW是Minimalist GNUfor Windows的缩写,可以简单理解成,用了它,Eclipse就可以把C++代码生成DLL文件~DLL文件就可以被java调用。是这么一个逻辑。
那么场长特定叮嘱,下载的时候一定要看清版本,有64位,也有32位,在安装的过程中一定要注意,否则会导致你一天的配置功亏一篑。
链接: https://pan.baidu.com/s/1c9BjKq 密码: a7q9
安装MinGW的时候,请参照攻略:
Win7 64位下安装配置mingw-w64 C++开发
https://jingyan.baidu.com/article/19192ad816ea01e53e570730.html
Win+R调出CMD窗口后,输入gcc -v,对,就是gcc,不是C++什么的,因为gcc就是MinGW的C++代号。出现下图:
我们可以看到64位的MinGW已安装到场长电脑里面啦~
然后就是安装Eclipse的C++ IDE插件啦~也就是CDT(C/C++ Development Toolkit)。我们选择菜单Help->Install New Software,安装CDT插件
选择第一个点击Next安装就可以啦~
接下来在系统环境变量PATH中添加MinGW的路径,具体为在“我的电脑”右击,点击“属性”,点击左侧的“高级系统设置”。在“系统属性”对话框内,选择顶部的“高级”页,然后点击“环境变量”。
声明MINGW_HOME的路径后,其他路径就可以用%MINGW_HOME%/bin等来代替就行。具体路径声明见下图。
同时,将C:\MinGW\bin下的文件“mingw32-make.exe”改名成“make.exe”,便于Eclipse直接调用此进行编译。因为要生成dll文件的时候,就需要选择make.exe。
Eclipse CDT的详细使用手则见链接:
使用MinGW + Eclipse CDT进行C++开发的配置方法
https://jingyan.baidu.com/article/380abd0a5888211d90192cd6.html
三、Java JNI编程生成C++头文件
创建一个Java project
在ec.app.batch子目录下创建一个名为“JavaCallCPlus”的Java project,创建一个名为“ec.app.batch.JavaCallCPlust”的class,其内容如下。同时在该project下创建resources文件夹,用来存放动态库文件。
package ec.app.batch;
public class JavaCallCPlus {
static{
System.loadLibrary("libInvokedCPlus");
}
public JavaCallCPlus() {}
public static void main(final String[] args) {
JavaCallCPlus shp = new JavaCallCPlus();
System.out.println(shp.getobj("(* (* PT RPT) (+ STPT MINSPT))")); }
//native方法声明
public native double getobj(String heuristic);
}
在命令行下,进入Java项目的bin文件夹(例如C:\Users\runse\eclipse-workspace\ECJ_New),右键点击“在此处点击命令窗口”,调出CMD窗口。
我们首先输入javah,看出现什么东西
我们可以看到javah -jni可以生成JNI样式的标准头文件,但这是默认值,也就是说,我们不输入-jni也是可以输出C++ 头文件的。我们点击输入java ec.app.batch.JavaCallCPlus,如下图
即可在bin目录下生成C++的头文件,其内容如下图。
我们点开这个头文件看看~
不难看出,JNI把java里面的Native函数对其进行处理,处理成C++可以识别的头文件。C++只需要把这个头文件放在项目中,就可以对java的Native函数进行编译,其函数的返回值又可以返回到java。从而实现了Java和C++之间的通信。
hhh,本场长今天就写到这里啦~~之后把整个算法做完之后,再写之后的步骤~唔...今晚有点累,帮师兄De了半天的BUG,十一点才回到宿舍。
晚安啦~
领取专属 10元无门槛券
私享最新 技术干货