下面是“Windows下VSCode+VS2019开发JNI的示例”的完整攻略。
背景介绍
Java Native Interface(JNI)是Java和本地C/C++代码交互的一种极其灵活的方式。JNI允许Java应用程序在其运行过程中调用本地C/C++应用程序,并让本地应用程序调用Java应用程序。该过程包括使用Java编写代码,编译Java代码生成Java类,调用Java类的JNI接口,使用C/C++编写本地代码,生成动态链接库(DLL),然后将DLL文件与Java应用程序一起部署。
本教程将介绍如何在Windows下使用VSCode和VS2019开发JNI的技巧,以及提供两个示例来帮助你理解JNI的具体应用。
前置条件
在开始本教程之前,请确保你已经安装了以下软件。
- Java SDK(1.8或更高版本)
- Visual Studio 2019
- VSCode
安装必要的插件
在安装好VSCode之后,你需要安装以下插件:
-
Java Extension Pack:这是一个官方提供的Java扩展插件包,包含了所有常用的Java扩展插件,可以让你更方便地编写和调试Java代码。
-
C/C++ Extension:用于在VSCode中调试C/C++代码
-
Debugger for Java:用于在VScode中调试Java代码
你可以在VSCode的插件市场中搜索并安装这些插件。
开发JNI的示例
示例一:Java调用C++的HelloWorld程序
下面是Java调用C++编写的HelloWorld示例,该示例中,我们将使用C++实现HelloWorld的逻辑,并将其封装为DLL文件,然后调用Java接口调用该DLL文件。
1.首先,我们需要创建一个VS2019项目,该项目将使用C++编写HelloWorld逻辑代码,并生成DLL文件。
在VS2019中,打开“新建项目”的窗口,选择“Visual C++”,然后选择“Win32”,将项目类型设置为“DLL”,设置所需的名称和保存路径。
2.在项目中创建一个名为“native.cpp”的C++源文件,实现如下代码逻辑:
#include "stdafx.h"
#include <iostream>
#include "native.h"
using namespace std;
JNIEXPORT void JNICALL Java_com_example_jni_NativeInterface_sayHello(JNIEnv *env, jobject thisObject) {
cout << "Hello, world!" << endl;
}
3.在项目中创建一个名为“native.h”的头文件,该文件应包含该函数的声明。
#include <jni.h>
#ifndef _Included_com_example_jni_NativeInterface
#define _Included_com_example_jni_NativeInterface
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_example_jni_NativeInterface_sayHello(JNIEnv *, jobject);
JNIEXPORT jstring JNICALL Java_com_example_jni_NativeInterface_sayTest(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4.编译项目并生成DLL文件。
在项目中,单击“F7”编译并构建。在构建成功后,在项目输出目录中将生成一个名为“native.dll”的文件。
5.创建Java项目
在VSCode中,创建一个简单的Java Maven项目,例如,我们将项目命名为“jnidemo”。在项目中,我们需要创建一个名为“NativeInterface.java”的Java接口,在其代码中,我们将定义调用C++ DLL文件的本地方法。
package com.example.jni;
public class NativeInterface {
public static native void sayHello();
public static native String sayTest();
}
将Java类编译成class文件。
使用以下命令在项目根目录下运行Maven以构建项目:
mvn compile
mvn package
6.将DLL文件包含在Java项目中
在Java项目上右键单击,选择“New File”,并将名称设置为“libloader.java”。该文件的代码如下:
package com.example.jni;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class LibLoader {
public static void loadLib(String libName) {
try {
String lib = System.mapLibraryName(libName);
File tempDir = new File(System.getProperty("java.io.tmpdir"), "jnidemo");
tempDir.mkdirs();
File libFile = new File(tempDir, lib);
if (!libFile.exists()) {
InputStream is = LibLoader.class.getClassLoader().getResourceAsStream(lib);
FileOutputStream os = new FileOutputStream(libFile);
byte[] buffer = new byte[1024];
int len = is.read(buffer);
while (len != -1) {
os.write(buffer, 0, len);
len = is.read(buffer);
}
os.close();
is.close();
}
System.load(libFile.getAbsolutePath());
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
该类的目的是将C++的DLL文件加载到Java类路径中。将下面的代码添加到项目的“Main.java”类中。
public static void main(String[] args) {
System.loadLibrary("native");
NativeInterface.sayHello();
}
在项目中,执行以下命令使其在“Main.java”的main方法中调用遇到问题时,输出Debug信息供我们调试:
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
LibLoader.loadLib("native");
NativeInterface.sayHello();
}
7.运行程序并查看输出。
在项目文件夹中,打开终端并运行“cmd”,在控制台中输入以下命令:
java -cp target/dependency/*;target/classes com.example.jni.Main
如果一切都设置正确,你应该能够看到以下输出:
C:\Users\username\AppData\Local\Temp\jnidemo\native.dll
Hello, world!
示例二:Java调用带参本地方法
下面是Java调用带参本地方法的示例。
1.创建C++项目并生成DLL文件
根据示例一的步骤,创建一个C++项目,实现以下代码:
#include "stdafx.h"
#include <iostream>
#include "com_example_jni_NativeInterface.h"
using namespace std;
JNIEXPORT void JNICALL Java_com_example_jni_NativeInterface_sayHello(JNIEnv *env, jobject thisObject, jstring name) {
cout << "Hello, " << JStringToString(env, name) << "!" << endl;
}
string JStringToString(JNIEnv * env, jstring jStr) {
const char *c_str = env->GetStringUTFChars(jStr, NULL);
string s(c_str);
env->ReleaseStringUTFChars(jStr, c_str);
return s;
}
2.创建Java接口。
在Java项目中,创建代码如下的Java接口“NativeInterface.java”。
package com.example.jni;
public class NativeInterface {
public static native void sayHello(String name);
}
并将其编译成class文件。
3.实现Java接口。
在Java项目中,创建一个名为“Main.java”的类,并实现其代码如下:
package com.example.jni;
public class Main {
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
LibLoader.loadLib("native");
NativeInterface.sayHello("JNI");
}
}
然后,执行以下命令,查看输出:
java -cp target/dependency/*;target/classes com.example.jni.Main
输出应为"Hello, JNI!"。
至此,我们已成功实现Java和C++之间的交互,这就是JNI技术的应用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:windows下vscode+vs2019开发JNI的示例 - Python技术站