1 JNI是什么?
Java Native Interface ,Java本地接口。它允许Java语言与其他语言编写的应用进行交互。JNI是本地编程接口,它使得Java VM内部运行的代码,能够与其他编程语言(比如 C\C++ 、汇编)编写的应用程序和库进行交互操作。关于JNI的具体说明文档,请查看:
http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
2 使用JNI实现Java本地调用
步骤:
1 编写包含本地方法的java程序;
2 使用javah生成头文件;
3 根据生成的头文件,实现本地方法;
4 编译成动态库文件;
5 使用,编写一个测试类。
下面是具体实现过程:
编写.java文件,下面我将1步和第5步写成了一个类 ,包括本地方法声明和加载动态库:
HelloWorld.java
public class HelloWorld{
public native int printNum();//本地方法声明
static{
System.loadLibrary("libHelloWorld");//加载动态库
}
public static void main(String[] args){
new HelloWorld().printNum();//调用本地方法
}
}
使用javac 命令编译,生成HelloWorld.class文件。
利用HelloWorld.class生成头文件,要想生成头文件,必须安装好JDK(当然,上一步假设你已经安装好!),
javah –classpath 包的上一级目录(一定要是这个) –jni 包名.类名
可以使用javah –help 来获取命令使用的方法
由于我这个并未指定包名,故直接:
javah -classpath HelloWorld.class -jni HelloWorld
生成的头文件:
HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> //包含文件,必须包含jni.h 它位于JDK的include目录中,是自动生成的
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld //预处理命令 如果后面的常量未定义,则返回true,执行后面的代码
#define _Included_HelloWorld //定义宏
#ifdef __cplusplus //如果后面的常量已被定义,返回true ,执行后面的代码
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: printNum
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_HelloWorld_printNum
(JNIEnv *, jobject); //本地方法原型,JNIEXPORT JNICALL都是宏名 ,jint 是返回的类型 ,Java_HelloWorld_printNum本地方法名,Java_全类名(用_隔开)_方法名,参数JNIEnv JNI环境变量, jobject java对象 注意此处只做了声明,并未指明形参,实现时要注意
#ifdef __cplusplus
}
#endif
#endif
实现具体的C文件:
HelloWorld.c
#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT jint JNICALL Java_HelloWorld_printNum
(JNIEnv *env, jobject obj){//本地方法的具体实现
printf("HelloWorld");
}
编译C文件,为了获得编译器,我下载了Dev c++工具,好处,我也可以使用它了编写C程序。然后配置环境变量,或切换目录到安装的bin目录下(在DOS环境中),使用命令:
gcc -c -I”E:/Java/jdk1.8.0_20/include” -I”E:/Java/jdk1.8.0_20/include/win32” -LD HelloWorld.c -FeHelloWorld.dll
以上得到.o中间文件。接着编译为so文件
gcc -o libHelloWorld.dll -shared -fPIC HelloWorld.o
然后使用java HelloWorld运行程序输出,如下: