windows下vscode+vs2019开发JNI的示例

下面是“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之后,你需要安装以下插件:

  1. Java Extension Pack:这是一个官方提供的Java扩展插件包,包含了所有常用的Java扩展插件,可以让你更方便地编写和调试Java代码。

  2. C/C++ Extension:用于在VSCode中调试C/C++代码

  3. 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技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java日期时间字符串和毫秒相互转换的方法

    下面是详细讲解Java日期时间字符串和毫秒相互转换的方法的攻略。 一、Java日期时间字符串转毫秒 1.1 SimpleDateFormat类 在Java中,可以使用SimpleDateFormat类来完成日期时间字符串的转换。SimpleDateFormat是Java中日期时间格式化类的一个子类,它继承了DateFormat类,提供了非常方便的日期时间格式…

    Java 2023年5月20日
    00
  • Spring Boot 接口加解密,新姿势来了!

    1. 介绍 在我们日常的Java开发中,免不了和其他系统的业务交互,或者微服务之间的接口调用 如果我们想保证数据传输的安全,对接口出参加密,入参解密。 但是不想写重复代码,我们可以提供一个通用starter,提供通用加密解密功能 2. 前置知识 2.1 hutool-crypto加密解密工具 hutool-crypto提供了很多加密解密工具,包括对称加密,非…

    Java 2023年4月17日
    00
  • java中的三种取整函数总结

    关于Java中三种取整函数的总结,我给出以下详细讲解。 一、背景 在Java编程中,我们有时需要对数字进行取整操作。Java中有三种常用的取整函数:向下取整(floor),四舍五入(round),向上取整(ceil),这些函数都属于Math类。 二、方法说明 下面分别对这三个方法进行详细说明。 1. floor(double a) 该方法是向下取整,表示将参…

    Java 2023年5月26日
    00
  • Spring Security基本架构与初始化操作流程详解

    Spring Security基本架构与初始化操作流程详解 介绍 Spring Security是一个基于Spring框架的安全性框架,处理了身份认证(authentication)与授权(authorization)等一系列的安全性问题,能够使我们更快更简单地集成到Spring应用程序中,保障应用程序的安全性。 本篇文章将会为您详细介绍Spring Sec…

    Java 2023年6月3日
    00
  • SpringBoot+SpringSecurity+jwt实现验证

    下面我会提供一个基于Spring Boot、Spring Security 和 JSON Web Token(JWT)的认证示例。 一、什么是JWT JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种简单的、自包含的方式,用于在通过网络进行传输的两个实体之间安全传递信息。它被称为自包含是因为JWT包含了所有身份验证(Aut…

    Java 2023年5月20日
    00
  • Java实现统计文档中关键字出现的次数

    为了实现统计文档中关键字出现的次数,我们需要以下步骤: 步骤一:获取文档内容 首先,我们需要读取文档中的内容,可以使用Java中的File类来进行文件的读取,示例代码如下: File file = new File("example.txt"); try { BufferedReader br = new BufferedReader(n…

    Java 2023年5月29日
    00
  • Spring Boot Cache使用方法整合代码实例

    下面我将详细讲解“Spring Boot Cache使用方法整合代码实例”的完整攻略。 一、什么是Spring Boot Cache Spring Boot Cache是Spring Boot中的缓存框架,它提供了一种简单的方式来缓存数据的读取结果,从而减少不必要的计算并提升应用程序的性能。 二、Spring Boot Cache使用方法 1. 引入依赖 在…

    Java 2023年5月31日
    00
  • 详解Java多线程编程中互斥锁ReentrantLock类的用法

    详解Java多线程编程中互斥锁ReentrantLock类的用法 简介 Java多线程编程中,为了保证线程安全,需要保证同一时间只有一个线程访问共享资源。使用互斥锁可以实现这个目的。在Java中,ReentrantLock类提供了互斥锁的功能。 ReentrantLock是可重入的互斥锁,它允许线程重复地获取同一把锁,而不会造成死锁。与synchronize…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部