最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java通過JNI調(diào)用C++動(dòng)態(tài)庫的完整流程詳解

 更新時(shí)間:2025年04月09日 09:17:10   作者:頗有幾分姿色  
JNI(Java Native Interface),是實(shí)現(xiàn)Java/Kotlin與C/C++語言之間交互的橋梁,本文主要為大家介紹了Java通過JNI調(diào)用C++動(dòng)態(tài)庫的完整流程,需要的可以參考下

介紹使用 JNI 調(diào)用 C++ 編寫的動(dòng)態(tài)鏈接庫的全過程。

示例環(huán)境

項(xiàng)目說明
JDK8
C++ 編譯器Visual Studio 2019
Java 開發(fā)工具IntelliJ IDEA 2021.3
操作系統(tǒng)Windows 10

Java 項(xiàng)目結(jié)構(gòu)概覽

編寫 Java 類

在 org.jni.nativejni 包下創(chuàng)建類 HelloWorldJni.java:

package org.jni.nativejni;

public class HelloWorldJni {

    static {
        // 加載 C++ 編譯生成的 DLL
        System.load("E:/vsproject/HelloWorld/x64/Release/HelloWorld.dll");
    }

    // native 方法聲明
    public native String sayHello(String str1, String str2);
    public native int add(int a, int b);

    public static void main(String[] args) {
        HelloWorldJni hw = new HelloWorldJni();
        System.out.println("拼接字符串:" + hw.sayHello("Hello", "World"));
        System.out.println("相加:" + hw.add(52, 23));
    }
}

生成 JNI 頭文件

方法一:使用 javac -h(推薦方式,支持 JDK8+)

在項(xiàng)目根目錄下執(zhí)行命令:

javac -h src/main/jni src/main/java/org/jni/nativejni/HelloWorldJni.java

說明:

  • -h 參數(shù)用于指定生成頭文件的目錄。
  • 這個(gè)命令會(huì)編譯 .java 文件然后生成 .class 文件,同時(shí)生成 JNI 頭文件。

注意:這個(gè)命令會(huì)在源碼目錄中生成 .class 文件,建議在 target/classes 中操作,避免污染源碼。

方法二:使用 javah(僅適用于 JDK8)

先使用 Maven 編譯項(xiàng)目:

mvn clean install

然后執(zhí)行:

javah -classpath target/classes -d src/main/jni org.jni.nativejni.HelloWorldJni

說明:

  • -classpath 指定 .class 文件的根路徑。
  • -d 指定 JNI 頭文件的輸出目錄。

實(shí)現(xiàn) JNI 層與調(diào)用 DLL 方法

使用 Visual Studio 編譯生成 DLL

1.創(chuàng)建一個(gè)新的 C++ DLL 項(xiàng)目,項(xiàng)目名稱為 HelloWorld。

2.添加源文件:

  • HelloWorld.cpp:實(shí)現(xiàn) DLL 的原始功能邏輯。
  • HelloWorldJNI.cpp:實(shí)現(xiàn) JNI 橋接代碼。

3.配置項(xiàng)目屬性:

C/C++ → 常規(guī) → 附加包含目錄中添加:

  • JDK 的 include 目錄
  • JDK 的 include/win32 目錄

C++ 頭文件:HelloWorld.h

#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H

// 導(dǎo)出 HelloWorld 函數(shù)
extern "C" __declspec(dllexport) const char* HelloWorld(const char* str1, const char* str2);

// 導(dǎo)出 Add 函數(shù)
extern "C" __declspec(dllexport) int Add(int a, int b);

#endif // HELLO_WORLD_H#pragma once

C++ 實(shí)現(xiàn):HelloWorld.cpp

// HelloWorld.cpp
#include "pch.h" // 如果 VS 生成了預(yù)編譯頭文件
#include "HelloWorld.h" // 引入頭文件
#include <iostream>
#include <string>

extern "C" __declspec(dllexport) const char* HelloWorld(const char* str1, const char* str2) {
    static std::string result; // 使用靜態(tài)變量存儲(chǔ)返回值,確保返回的指針有效
    result = std::string(str1) + "," + std::string(str2);
    return result.c_str(); // 返回拼接后的 C 字符串
}

// 一個(gè)簡(jiǎn)單的加法函數(shù)
extern "C" __declspec(dllexport) int Add(int a, int b) {
    return a + b;
}

JNI 頭文件:org_jni_nativejni_HelloWorldJni.h

由 javac -h 或 javah 自動(dòng)生成,內(nèi)容如下:

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

#ifndef _Included_org_jni_nativejni_HelloWorldJni
#define _Included_org_jni_nativejni_HelloWorldJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     org_jni_nativejni_HelloWorldJni
 * Method:    sayHello
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_org_jni_nativejni_HelloWorldJni_sayHello
  (JNIEnv *, jobject, jstring, jstring);

/*
 * Class:     org_jni_nativejni_HelloWorldJni
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_org_jni_nativejni_HelloWorldJni_add
  (JNIEnv *, jobject, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

JNI 實(shí)現(xiàn):HelloWorldJNI.cpp

#include "pch.h" // 如果 VS 生成了預(yù)編譯頭文件
#include "org_jni_nativejni_HelloWorldJni.h"  // 引入自動(dòng)生成的 JNI 頭文件
#include "HelloWorld.h"    // 引入自定義的頭文件,調(diào)用已有的 DLL 接口

JNIEXPORT jstring JNICALL Java_org_jni_nativejni_HelloWorldJni_sayHello
(JNIEnv* env, jobject, jstring jStr1, jstring jStr2) {
    // 將 Java 字符串轉(zhuǎn)換為 C 字符串
    const char* str1 = env->GetStringUTFChars(jStr1, nullptr);
    const char* str2 = env->GetStringUTFChars(jStr2, nullptr);

    // 調(diào)用 C++ 動(dòng)態(tài)庫函數(shù)
    const char* result = HelloWorld(str1, str2);

    // 釋放 Java 字符串的本地內(nèi)存
    env->ReleaseStringUTFChars(jStr1, str1);
    env->ReleaseStringUTFChars(jStr2, str2);

    // 將 C 字符串轉(zhuǎn)換為 Java 字符串并返回
    return env->NewStringUTF(result);
}


JNIEXPORT jint JNICALL Java_org_jni_nativejni_HelloWorldJni_add
(JNIEnv*, jobject, jint a, jint b) {
    return Add(a, b); // 調(diào)用原始的 Add 函數(shù)
}

提示:這里為了演示方便,JNI 橋接代碼和業(yè)務(wù)邏輯放在同一個(gè)項(xiàng)目中。實(shí)際開發(fā)時(shí)橋接層要單獨(dú)封裝,便于維護(hù)與復(fù)用。

Java 調(diào)用 DLL 測(cè)試

將編譯生成的 HelloWorld.dll 放到系統(tǒng)環(huán)境變量中,這里這個(gè)庫沒什么其他依賴,都是系統(tǒng) c 盤中有的,所以直接指到它生成的目錄就可以使用了。

運(yùn)行 Java 主類的輸出結(jié)果:

拼接字符串:Hello,World
相加:75

總結(jié)

梳理一下 Java 調(diào)用 C++ DLL 的完整流程。主要包括:

  • 編寫 Java 類并聲明 native 方法
  • 使用 javac -h 或 javah 生成 JNI 頭文件
  • 實(shí)現(xiàn) JNI 橋接層,調(diào)用 DLL 中的 C++ 方法
  • 使用 Visual Studio 生成 DLL 文件
  • Java 運(yùn)行時(shí)加載并調(diào)用本地方法,或者封裝成接口給別人使用。

到此這篇關(guān)于Java通過JNI調(diào)用C++動(dòng)態(tài)庫的完整流程詳解的文章就介紹到這了,更多相關(guān)Java JNI調(diào)用C++動(dòng)態(tài)庫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaGUI常用窗體組件與面板使用詳解

    JavaGUI常用窗體組件與面板使用詳解

    GUI即圖形用戶界面,它是基于圖形的界面,windows就是一個(gè)圖形用戶界面的操作系統(tǒng),而DOS是基于命令提示符的操作系統(tǒng),GUI編程就是編出一個(gè)圖形用戶界面的軟件,它使用圖形的方式,以菜單、按鈕、表示、圖文框等標(biāo)準(zhǔn)界面元素組成的用戶操作界面
    2023-03-03
  • SpringBoot啟動(dòng)流程SpringApplication準(zhǔn)備階段源碼分析

    SpringBoot啟動(dòng)流程SpringApplication準(zhǔn)備階段源碼分析

    這篇文章主要為大家介紹了SpringBoot啟動(dòng)流程SpringApplication準(zhǔn)備階段源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java中ArrayIndexOutOfBoundsException 異常報(bào)錯(cuò)的解決方案

    Java中ArrayIndexOutOfBoundsException 異常報(bào)錯(cuò)的解決方案

    本文主要介紹了Java中ArrayIndexOutOfBoundsException 異常報(bào)錯(cuò)的解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • java中流的使用

    java中流的使用

    本文主要介紹了java中流的使用以及分類。具有一定的參考價(jià)值,下面跟著小編一起來看下吧
    2017-01-01
  • java解析Excel的方法(xls、xlsx兩種格式)

    java解析Excel的方法(xls、xlsx兩種格式)

    這篇文章主要介紹了java解析Excel的方法(xls、xlsx兩種格式),需要的朋友可以參考下
    2018-04-04
  • Java  隊(duì)列 Queue 用法實(shí)例詳解

    Java 隊(duì)列 Queue 用法實(shí)例詳解

    本文實(shí)例講述了Java內(nèi)置隊(duì)列類Queue用法,分享給大家供大家參考
    2017-04-04
  • Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解

    Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解

    在本篇文章里小編給大家分享的是關(guān)于Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解,有需要的朋友們可以參考下。
    2019-10-10
  • Spring Boot 排除某個(gè)類加載注入IOC的操作

    Spring Boot 排除某個(gè)類加載注入IOC的操作

    這篇文章主要介紹了Spring Boot 排除某個(gè)類加載注入IOC的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot如何獲取src/main/resource路徑下的文件

    SpringBoot如何獲取src/main/resource路徑下的文件

    這篇文章主要介紹了SpringBoot如何獲取src/main/resource路徑下的文件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Springboot2.6.x高版本與Swagger2版本沖突問題解決方法

    Springboot2.6.x高版本與Swagger2版本沖突問題解決方法

    Spring Boot 2.6.x版本引入依賴?springfox-boot-starter?(Swagger?3.0) 后,啟動(dòng)容器會(huì)報(bào)錯(cuò),本文就介紹一下Springboot2.6.x高版本與Swagger2版本沖突問題解決方法,感興趣的可以了解一下
    2022-04-04

最新評(píng)論

定襄县| 太保市| 花莲县| 泽州县| 大城县| 金乡县| 潮安县| 安远县| 临泉县| 云安县| 安仁县| 曲靖市| 馆陶县| 德钦县| 安阳市| 庆阳市| 罗甸县| 河北省| 平定县| 临洮县| 石泉县| 宜昌市| 洪江市| 汶川县| 黄大仙区| 杭锦旗| 昌图县| 安庆市| 芜湖市| 北安市| 天镇县| 甘洛县| 清远市| 奉节县| 静安区| 九江市| 集安市| 成都市| 桐梓县| 新建县| 类乌齐县|