前言
JNI,即Java Native Interface,java本地接口,就是在java程序中可以调用C语言或C++程序。
java源码中就有很多使用到JNI的地方,如Thread.start0()
JNI编写流程
创建包含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头文件
两个头文件都在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调用
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()使用动态链接库名称,但需要配置环境变量。
输出结果为
Hello JNI!
参考
Java 之JNI基础篇(一)