JAVA JNI

作者: const27 分类: All,开发-JAVA 发布时间: 2020-12-15 09:12

JNI是JAVA的一个接口,用来实现c/c++调用,为JAVA提供了一个操纵底层的能力。

JNI HelloWorld

java IDE:idea C IDE:vs2019

1.写好JAVA文件,定义好native方法。

public class test {
    static{
        System.loadLibrary("Dll1");
    }
    public native void hello();
    public static void main(String[] args) {
        test a = new test();
        a.hello();
    }
}

2.使用javac指令为java文件的各native方法生成c语言头文件。

javac -cp . test.java -h .

执行后会在当前目录下生成一个头文件

3.用vscode创建一个dll项目,将test.h与jdk include目录下的jni.h以及jdk/include/win32/jni_md.h统统移动到项目文件目录下。然后在vscode头文件里添加现有项,把刚刚放到项目文件下的3个头文件添加进去。

4.在c或c++中定义native方法的c/c++原型。

通过test.h我们可以看到哪些方法需要我们定义。这里是Java_test_hello方法。

我们随便定义一下

#include "test.h"

JNIEXPORT void JNICALL Java_test_hello(JNIEnv* a, jobject b) {
	printf("Hello,World");
}

编译为dll文件。

5.在idea里为当前项目指定依赖dll文件路径

先点击箭头指向处的编辑选项,然后在虚拟机选项里填上-Djava.library.path=你的dll路径

6.把dll文件拖进刚刚配置好的依赖路径,运行

JNI 数据类型

JNI类型数据在c文件里当作传入参数和返回结果,参数传入后其数据类型会被用指定方法转换为C类型然后被处理,处理完毕后使用指定方法转换为JNI类型返回给JAVA。

这里介绍一下c中JNI类型与c类型互转的函数

jstring转char*:env->GetStringUTFChars(str, &jsCopy)

char*转jstring: env->NewStringUTF("Hello...")

字符串资源释放: env->ReleaseStringUTFChars(javaString, p);

JNI 实现本地命令执行

相当于一个加强版的helloworld.

首先我们看一下,如果在c++中我们想执行本地命令执行该如何执行

#include<iostream>
#include<stdio.h>
#include <string>

std::string gogo(const char* cmd) {
	const char* cmd = cmd;
	FILE* fp = _popen(cmd, "r");
	if (fp != NULL) {
		std::string result;
		char buf[128];
		while (fgets(buf, sizeof(buf), fp) != NULL) {
			result += buf;
		}
		return result;
	}
}

int main() {
	std::string result = gogo("dir");
	std::cout << result;
}

那么我们在JNI里如何实现呢?其实也差不多.

我们现在写好java代码


public class test {
    static{
        System.loadLibrary("Dll2");
    }
    public native String gogo(String cmd);
    public static void main(String[] args) {
        test a = new test();
        String str = a.gogo("dir");
        System.out.println(str);
    }
}

写好c++代码

#include "test.h"
#include<iostream>
#include<stdio.h>
#include <string>
JNIEXPORT jstring JNICALL Java_test_gogo(JNIEnv* env, jobject obj, jstring str) {
	 const char* cmd = env->GetStringUTFChars(str, 0);
	 FILE* fd = _popen(cmd, "r");
	 if (fd != NULL) {
		 std::string result;
		 char buf[128];
		 while (fgets(buf, sizeof(buf), fd) != NULL) {
			 result += buf;
		 }
		 _pclose(fd);
		 return env->NewStringUTF(result.c_str());
	 }
}

运行结果

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

3 × 2 =

标签云