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

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

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

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

示例環(huán)境

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

Java 項目結構概覽

編寫 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+)

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

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

說明:

  • -h 參數用于指定生成頭文件的目錄。
  • 這個命令會編譯 .java 文件然后生成 .class 文件,同時生成 JNI 頭文件。

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

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

先使用 Maven 編譯項目:

mvn clean install

然后執(zhí)行:

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

說明:

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

實現(xiàn) JNI 層與調用 DLL 方法

使用 Visual Studio 編譯生成 DLL

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

2.添加源文件:

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

3.配置項目屬性:

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

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

C++ 頭文件:HelloWorld.h

#ifndef HELLO_WORLD_H
#define HELLO_WORLD_H

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

// 導出 Add 函數
extern "C" __declspec(dllexport) int Add(int a, int b);

#endif // HELLO_WORLD_H#pragma once

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

// HelloWorld.cpp
#include "pch.h" // 如果 VS 生成了預編譯頭文件
#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)變量存儲返回值,確保返回的指針有效
    result = std::string(str1) + "," + std::string(str2);
    return result.c_str(); // 返回拼接后的 C 字符串
}

// 一個簡單的加法函數
extern "C" __declspec(dllexport) int Add(int a, int b) {
    return a + b;
}

JNI 頭文件:org_jni_nativejni_HelloWorldJni.h

由 javac -h 或 javah 自動生成,內容如下:

/* 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 實現(xiàn):HelloWorldJNI.cpp

#include "pch.h" // 如果 VS 生成了預編譯頭文件
#include "org_jni_nativejni_HelloWorldJni.h"  // 引入自動生成的 JNI 頭文件
#include "HelloWorld.h"    // 引入自定義的頭文件,調用已有的 DLL 接口

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

    // 調用 C++ 動態(tài)庫函數
    const char* result = HelloWorld(str1, str2);

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

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


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

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

Java 調用 DLL 測試

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

運行 Java 主類的輸出結果:

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

總結

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

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

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

相關文章

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

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

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

    SpringBoot啟動流程SpringApplication準備階段源碼分析

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

    Java中ArrayIndexOutOfBoundsException 異常報錯的解決方案

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

    java中流的使用

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

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

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

    Java 隊列 Queue 用法實例詳解

    本文實例講述了Java內置隊列類Queue用法,分享給大家供大家參考
    2017-04-04
  • Java控制結構知識點詳解

    Java控制結構知識點詳解

    在本篇文章里小編給大家分享的是關于Java控制結構知識點詳解,有需要的朋友們可以參考下。
    2019-10-10
  • Spring Boot 排除某個類加載注入IOC的操作

    Spring Boot 排除某個類加載注入IOC的操作

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

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

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

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

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

最新評論

新野县| 陇川县| 石景山区| 南宁市| 东城区| 崇信县| 富平县| 安吉县| 郸城县| 永新县| 庄浪县| 香港 | 开江县| 鲁甸县| 冷水江市| 弥渡县| 修武县| 星子县| 垣曲县| 泰来县| 文安县| 郑州市| 邹城市| 兴城市| 荥经县| 米林县| 任丘市| 金坛市| 呼伦贝尔市| 彝良县| 石嘴山市| 周至县| 青冈县| 崇左市| 墨脱县| 顺义区| 安康市| 日喀则市| 宁远县| 宁乡县| 将乐县|