前言

JNI,即Java Native Interface,java本地接口,就是在java程序中可以调用C语言或C++程序。
java源码中就有很多使用到JNI的地方,如Thread.start0()

java平方的头文件 java jni 头文件_java平方的头文件

JNI编写流程

java平方的头文件 java jni 头文件_C语言_02

创建包含native方法的java类并编译

public class TestJNI {

  public native void sayHello();
}

简单起见,TestJNI类没有包名。

生成头文件

  • java8中使用命令
javah -jni -o testjni.h TestJNI

o表示生成文件名,生成的头文件内容如下

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

#ifndef _Included_TestJNI
#define _Included_TestJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     TestJNI
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_TestJNI_sayHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
  • java11中使用命令
    java11已经移除了javah命令
javac -h . TestJNI.java

直接根据源码生成头文件,文件内容和上面一样。

方法实现及DLL文件打包

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

#ifndef _Included_TestJNI
#define _Included_TestJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     TestJNI
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_TestJNI_sayHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

在生成的头文件中添加jni.h头文件,windows平台下也要添加jni_md.h头文件

java平方的头文件 java jni 头文件_dll_03


java平方的头文件 java jni 头文件_头文件_04

两个头文件都在jdk的目录中

#include "jni.h"
#include "jni_md.h"
#include "TestJNI.h"

/*
 * Class:     TestJNI
 * Method:    sayHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_TestJNI_sayHello(JNIEnv *env, jobject obj) {
    printf("Hello JNI!");
}

关于如何打包成dll文件,可以参考 使用CLion创建C语言动态链接库DLL文件 这篇博客。

java平方的头文件 java jni 头文件_java平方的头文件_05

java调用

public class Client {

  public static void main(String[] args) {
//    System.load("D:\\java\\jdk\\libtestjni.dll");
    System.loadLibrary("libtestjni");
    new TestJNI().sayHello();
  }

}

有两种加载dll文件的方式,System.load()方法使用绝对路径,System.loadLibrary()使用动态链接库名称,但需要配置环境变量。

java平方的头文件 java jni 头文件_java_06

输出结果为

Hello JNI!

参考

Java 之JNI基础篇(一)