1 JNI是什么?

Java Native Interface ,Java本地接口。它允许Java语言与其他语言编写的应用进行交互。JNI是本地编程接口,它使得Java VM内部运行的代码,能够与其他编程语言(比如 C\C++ 、汇编)编写的应用程序和库进行交互操作。

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运行程序输出,如下:

java jmc 使用 java jni_本地方法