1、JNI介绍
JNI是Java Native Interface的缩写,中文为JAVA本地调用。从Java1.1开始,Java Native Interface(JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。
2、JNI代码生成步骤
JNI的使用核心是基于.java文件,首先编写.java的代码,然后使用javac编译.java文件,编译完成后;再使用javah编译生成.h头文件,.cpp文件由开发者自行添加。
2.1、HelloWorld范例(此范例中的文件、命令均在同一目录中):
2.1.1、编译java文件
java代码:
class HelloWorld
{
public native void displayHelloWorld();
static{
System.loadLibrary("JNI");
}
public static void main(String[] args){
new HelloWorld().displayHelloWorld();
}
}
编译java代码:
javac HelloWorld.java
2.1.2、生成C++头文件
编译C++头文件的前提:必须成功编译生成.class文件。
然后再编译生成C++头文件:
javah HelloWorld运行后,生成HelloWorld.h文件,.cpp文件需开发者自己添加。
3、SampleJNI范例(基于Java原生命令)
3.1、Java代码
FileGdbService.java代码:
package com.zjasm.filegdb.services;
public class FileGdbService {
static {
System.loadLibrary("FileGDBService");
}
public static native void createFeatureClass();
public static void main(String[] args) {
FileGdbService fileGdbService = new FileGdbService();
fileGdbService.createFeatureClass();
}
}
FileGdbService.java目录,特别注意文件目录必须与"package com.test.filegdb.services;"相对应,也就是必须存在com、test、filegdb、services这些目录,且FileGdbService.java文件保存在services目录中
3.2、工程目录
根目录:
子目录相对关系:
3.3、编译命令
3.3.1、编译FileGdbService.java
当前目录定位到services(cd com\zjasm\filegdb\services),在此目录下编译FileGdbService.java
javac FileGdbService.java
3.3.2、运行FileGdbService
运行前,目录需重新定位到com目录(cd ..\..\..\..\),在此目录下运行
java com.zjasm.filegdb.service.FileGdbService
3.4、注意事项
a、java文件中的package关系必须与文件的实际路劲对应
b、Java文件的名字、类名必须与C++头文件中的函数名对应
c、java运行区分32、64位虚拟机,所以提供的dll也必须严格区分32、64位
4、SampleJNIe范例(基于Eclipse、VS2012联调)
之前没处理过Java与C++联调的东西,印象中都是通过VS2012挂接到程序进程上,但是通过java命令执行的程序,通过console运行,vs无法挂接到。最终想到现将java工程整成jar包,再弄成.exe可执行程序(Exej4支持将.jar弄成.exe,具体步骤见5)。
尝试了多种方式后,发现基于Eclipse、VS的方案最好,Eclipse构建java的项目,VS构建C++的库。然后在Eclipse中运行Java程序,在VS中下断点,通过VS的“挂接到进程”,找到Eclipse的进程(javaw,一般都是这个),即可获取到VS的断点。
5、Exej4使用说明