← 返回首页
JavaSE系列教程(八十八)
发表时间:2020-03-01 12:47:14
讲解java native方法。

1.什么是native方法

native:即Java Native Interface。简单来说,一个用native关键字修饰的方法就是一个java调用非java代码的接口;

native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在用其他语言(如C和C++)实现的文件中,这个特征并非java语言所特有,很多其它编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数;

2.native方法实例

可以将native方法比作Java程序同C程序的接口,其实现步骤:

1)在Java中声明native()方法,然后编译;

2)用javah产生一个.h文件;

3)写一个.cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(注意其中又包含了JDK带的jni.h文件);

4)将第三步的.cpp文件编译成动态链接库文件;

5)在Java中用System.loadLibrary()方法加载第四步产生的动态链接库文件,这个native()方法就可以在Java中被访问了。

JNI 调用 C 流程图如下:

编写HelloNative.java,什么native方法。

public class HelloNative
{
    static
    {
        System.loadLibrary("HelloNative"); //实际去加载HelloNative.dll
    }

    public static native void sayHello();

    @SuppressWarnings("static-access")
    public static void main(String[] args)
    {
        new HelloNative().sayHello();
    }
}

编译生成class文件。

javac HelloNative.java

生成*.h头文件。

javah -jni HelloNative

注意:==JDK10以上bin目录以及不提供javah命令,编译头文件命令改写如下==:

javac -h jni HelloNative.java

HelloNative.h头文件,内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloNative
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloNative_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

将%JAVA_HOME%/include/jni.h和%JAVA_HOME%/include/win32/jni_md.h,两个头文件复制到和HelloNative.h所在的目录,并修改HelloNative.h的#include 为#include "jni.h",代码如下所示:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloNative
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloNative_sayHello
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

创建HelloNative.cpp源文件,内容如下:

#include "stdio.h"
#include "HelloNative.h"

JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv * env, jclass o) {
    printf("%s","Hello! JNI! ");//打印信息
    return;
}

使用Dev-C++,创建一个dll项目。选项如下图,注意项目的名字一定要命名为HelloNative:

删除项目自动生成的dllmain.cpp和dll.h文件,重新构建项目结构图如下:

编译HelloNative.cpp,会生成HelloNative.dll.

生成后的目录文件结构图,如下:

执行以下命令:

java HelloNative

出现运行结果如下图:

如果不出现运行结果,可以把dll所在路径,添加到path环境变量,或者把dll复制到Windows/System32或者 Windows/SysWOW64 目录下。