天天看点

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

什么是JNI

JNI是Java Native Interface的缩写,中文为JAVA本地调用。使用JNI可以很方便的用我们的Java程序调用C/C++程序。

很多时候,某些功能用Java无法实现,比如说涉及到底层驱动的一些功能,这时候我们就可以利用JNI来调用C或者C++程序来实现,这就是JNI的强大之处。但是JNI也有它的缺点,使用java与本地已编译的代码交互,通常会丧失平台可移植性。

Java接口

public class hello {
    {
    	System.load("C:\\Users\\Administrator\\IdeaProjects\\untitled1\\src\\Dll1.dll");
    //加载其他函数的驱动,是个dll文件
    }
    public native void sayHello();
    public static void main(String[] args){
        new hello().sayHello();
    }
}
           

可以看出,要想调用其他语言的接口,我们需要一个dll文件,那什么是dll文件?DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。

使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。

实现步骤

创建一个hello类,如下

public class hello {
    public native void sayHello();	//声明一个原生函数,是由c/c++实现
    public static void main(String[] args){
        new hello().sayHello();	//调用该方法.
    }
}
           

Dos命令编译

javac hello.java
javac -h -jni hello.java
//jdk10已经移除javah工具,相应的功能已经集成到javac中
           
效果如下
JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结
JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

我们的目的是生成 . h文件

hello.h

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

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

#ifdef __cplusplus
}
#endif
#endif
           

其中如下是C/C++函数接口,我们需要实现该方法

JNIEXPORT void JNICALL Java_hello_sayHello
  (JNIEnv *, jobject);
           

使用VS创建DLL项目

这里我使用的是VS2019版本.

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

在默认生成的dllmain.cpp加入如下代码

#include "pch.h"	//默认生成的
#include <iostream>
#include "jni.h"	//需要加入的
#include "hello.h"	//需要加入的
using namespace std;
JNIEXPORT void JNICALL Java_hello_sayHello
(JNIEnv*, jobject) {
	cout << "Hello java" << endl;
}
           

该cpp文件原有代码可以保留

我们需要jni.h和hello.h这两个头文件,所以我们把这两个头文件放到该项目下。

其中jni.h在jdk在安装目录下的include文件夹里

hello.h是我们刚刚生成的,最终如下图所示:

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

问题是,使用vs默认生成的dll是32位的,这里我们需要使用64位的dll,不然会发生版本不兼容的情况。

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结
JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

生成Dll

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结
JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

在java文件中引用dll文件

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

这里填写的是dll的文件所在目录。

运行程序

JNI详细调用(附带图文)什么是JNIJava接口实现步骤总结

总结

最终,输出的结果是Hello java,是我们用c++输出的,可见结果正确,我们也确实调用C/C++程序。