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

java調(diào)用動(dòng)態(tài)庫dll詳細(xì)示例代碼

 更新時(shí)間:2026年02月08日 10:00:57   作者:市場部需要一個(gè)軟件開發(fā)崗位  
最近應(yīng)項(xiàng)目的需求,需要通過java調(diào)用dll動(dòng)態(tài)庫,于是找了一些資料,在此記錄一下實(shí)現(xiàn)過程,這篇文章主要介紹了java調(diào)用動(dòng)態(tài)庫dll的相關(guān)資料,需要的朋友可以參考下

數(shù)據(jù)類型對應(yīng)關(guān)系

Java TypeC Type
booleanint
bytechar
charwchar_t
shortshort
doubledouble
floatfloat
Stringchar*

JNI 調(diào)用 dll

示例

  1. 包jni中新建java文件,JniDemo.java
package jni;

public class JniDemo {
    public native static void set(int i);
    public native static int get();
}
  1. 使用javah命令生成頭文件(jni_JniDemo.h)
javah jni.JniDemo
  1. vs2017創(chuàng)建項(xiàng)目 - Visual C++ - Windows 桌面 - 動(dòng)態(tài)鏈接庫(DLL)
    新建項(xiàng)目JniDemo
    注:選錯(cuò)了工程類型報(bào)錯(cuò)(UnsatisfiedLinkError: dll: 此操作僅在應(yīng)用容器上下文中有效。)

  2. 拷貝jni_JniDemo.h,jni.h,jni_md.h至vs工程cpp文件目錄下
    jni.h在D:\Java\jdk1.8.0_111\include\jni.h
    jni_md.h在D:\Java\jdk1.8.0_111\include\win32\jni_md.h

  3. 編輯文件
    修改文件jni_JniDemo.h:

#include <jni.h> 改為 #include "jni.h"

修改文件JniDemo.cpp:

#include "stdafx.h"
#include "jni_JniDemo.h"

int number = 0;

JNIEXPORT void JNICALL Java_jni_JniDemo_set
(JNIEnv *, jclass, jint i)
{
	number = i;
}

JNIEXPORT jint JNICALL Java_jni_JniDemo_get
(JNIEnv *, jclass)
{
	return number;
}
  1. 生成64位dll庫
    文件位置:D:\vsrepos\JniDemo\Release\JniDemo.dll

  2. 把64位dll庫拷貝至Java JniDemo項(xiàng)目根目錄下,修改JniDemo.java

public class JniDemo {
    static{
        System.loadLibrary("JniDemo");
    }
    public native static void set(int i);
    public native static int get();

    public static void main(String[] args) {
//        System.out.println(System.getProperty("java.library.path"));
        set(100);
        System.out.println(get());
    }
}

缺點(diǎn)

如果有一個(gè)現(xiàn)有的.dll/.so文件,如果使用JNI技術(shù)調(diào)用,我們首先需要另外使用C語言寫一個(gè).dll/.so共享庫,使用SUN規(guī)定的數(shù)據(jù)結(jié)構(gòu)替代C語言的數(shù)據(jù)結(jié)構(gòu),調(diào)用已有的 dll/so中公布的函數(shù)。

然后再在Java中載入這個(gè)適配器dll/so,再編寫Java native函數(shù)作為dll中函數(shù)的代理。

Jnative 調(diào)用 dll

Jnative是對JNI技術(shù)進(jìn)行了封裝,更加方便的讓java去調(diào)用DLL

JNA調(diào)用dll

JNA全稱Java Native Access
https://blog.csdn.net/gwd1154978352/article/details/55097376/
JNA中,它提供了一個(gè)動(dòng)態(tài)的C語言編寫的轉(zhuǎn)發(fā)器,可以自動(dòng)實(shí)現(xiàn)Java和C的數(shù)據(jù)類型映射。不再需要編寫C動(dòng)態(tài)鏈接庫。

地址:https://github.com/java-native-access/jna

<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>5.3.1</version>
</dependency

JNA沒辦法直接調(diào)用類方法,需要將類方法“取出來”重新封裝一遍。同時(shí)為了保持類的特性,每個(gè)方法增加一個(gè)參數(shù),用于傳遞類對象的引用。

示例

需要定義一個(gè)接口,繼承自Library 或StdCallLibrary

public interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary)
        Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
                           CLibrary.class);

    void printf(String format, Object... args);
}

搜索動(dòng)態(tài)鏈接庫路徑的順序是:先從當(dāng)前類的當(dāng)前文件夾找,如果沒有找到,再在工程當(dāng)前文件夾下面找win32/win64文件夾,找到后搜索對應(yīng)的dll文件,如果找不到再到WINDOWS下面去搜索,再找不到就會(huì)拋異常了。

JNA模擬結(jié)構(gòu)體

Structure 子類中的公共字段的順序,必須與C 語言中的結(jié)構(gòu)的順序一致。否則會(huì)報(bào)錯(cuò)!

c:

struct UserStruct{
long id;
wchar_t* name;
int age;
};

jna:

public static class UserStruct extends Structure{
    public NativeLong id;
    public WString name;
    public int age;
    public static class ByReference extends UserStruct
implements Structure.ByReference { }
    public static class ByValue extends UserStruct implements
Structure.ByValue
{ }
}
public void sayUser(UserStruct.ByReference struct);

Structure 類有兩個(gè)內(nèi)部接口Structure.ByReference 和Structure.ByValue。這兩個(gè)接口僅僅是標(biāo)記,如果一個(gè)類實(shí)現(xiàn)Structure.ByReference 接口,就表示這個(gè)類代表結(jié)構(gòu)體指針。

如果一個(gè)類實(shí)現(xiàn)Structure.ByValue 接口,就表示這個(gè)類代表結(jié)構(gòu)體本身。

JNA模擬復(fù)雜結(jié)構(gòu)體

c:

struct CompanyStruct{
long id;
wchar_t* name;
UserStruct users[100];
int count;
};

jna:

public static class CompanyStruct extends Structure{
public NativeLong id;
public WString name;
public UserStruct.ByValue[] users=new UserStruct.ByValue[100];
public int count;
}

測試代碼:

CompanyStruct2.ByReference companyStruct2=new CompanyStruct2.ByReference();
companyStruct2.id=new NativeLong(2);
companyStruct2.name=new WString("Yahoo");
companyStruct2.count=10;
UserStruct.ByReference pUserStruct=new
UserStruct.ByReference();
pUserStruct.id=new NativeLong(90);
pUserStruct.age=99;
pUserStruct.name=new WString("楊致遠(yuǎn)");
// pUserStruct.write();
for(int i=0;i<companyStruct2.count;i++){
companyStruct2.users[i]=pUserStruct;
}
 
TestDll1.INSTANCE.sayCompany2(companyStruct2);

考察JNI 技術(shù),我們發(fā)現(xiàn)Java 調(diào)用原生函數(shù)時(shí),會(huì)把傳遞給原生函數(shù)的Java 數(shù)據(jù)固定在內(nèi)存中,這樣原生函數(shù)才可以訪問這些Java 數(shù)據(jù)。對于沒有固定住的Java 對象,GC 可以刪除它,也可以移動(dòng)它在內(nèi)存中的位置,以使堆上的內(nèi)存連續(xù)。如果原生函數(shù)訪問沒有被固定住的Java 對象,就會(huì)導(dǎo)致調(diào)用失敗。

固定住哪些java 對象,是JVM 根據(jù)原生函數(shù)調(diào)用自動(dòng)判斷的。而上面的CompanyStruct2結(jié)構(gòu)體中的一個(gè)字段是UserStruct 對象指針的數(shù)組,因此,JVM 在執(zhí)行時(shí)只是固定住了CompanyStruct2 對象的內(nèi)存,而沒有固定住users 字段引用的UserStruct 數(shù)組。因此,造成了錯(cuò)誤。

我們需要把users 字段引用的UserStruct 數(shù)組的所有成員也全部固定住,禁止GC 移動(dòng)或者刪除。

如果我們執(zhí)行了pUserStruct.write();這段代碼,那么就可以成功執(zhí)行上述代碼。

Structure 類的write()方法會(huì)把結(jié)構(gòu)體的所有字段固定住,使原生函數(shù)可以訪問。

總結(jié)

到此這篇關(guān)于java調(diào)用動(dòng)態(tài)庫dll的文章就介紹到這了,更多相關(guān)java調(diào)用動(dòng)態(tài)庫dll內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java反射如何有效的修改final屬性值詳解

    Java反射如何有效的修改final屬性值詳解

    最近在工作中遇到一個(gè)需求,要利用反射對修飾符為final的成員變量進(jìn)行修改,所以這篇文章主要給大家介紹了關(guān)于Java反射如何有效的修改final屬性值的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對需要的朋友可以參考下。
    2017-08-08
  • IDEA啟動(dòng)Java?Spring舊項(xiàng)目的具體配置步驟

    IDEA啟動(dòng)Java?Spring舊項(xiàng)目的具體配置步驟

    剛剛接觸到IDEA,創(chuàng)建springboot總出現(xiàn)各種問題,這篇文章主要介紹了IDEA啟動(dòng)Java?Spring舊項(xiàng)目的具體配置步驟,文中通過圖文及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-10-10
  • Unity&Springboot實(shí)現(xiàn)本地登陸驗(yàn)證

    Unity&Springboot實(shí)現(xiàn)本地登陸驗(yàn)證

    本文主要介紹了Unity&Springboot服務(wù)器/本地登陸驗(yàn)證,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java二叉樹的四種遍歷方式詳解

    Java二叉樹的四種遍歷方式詳解

    這篇文章主要介紹了Java二叉樹的四種遍歷,二叉樹的遍歷可以分為前序、中序、后序、層次遍歷,需要的朋友可以參考下
    2021-11-11
  • Spring?Data?Jpa返回自定義對象的3種方法實(shí)例

    Spring?Data?Jpa返回自定義對象的3種方法實(shí)例

    在使用Spring Data Jpa框架時(shí),根據(jù)業(yè)務(wù)需求我們通常需要進(jìn)行復(fù)雜的數(shù)據(jù)庫查詢,下面這篇文章主要給大家介紹了關(guān)于Spring?Data?Jpa返回自定義對象的3種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • SpringCloud Config配置中心原理以及環(huán)境切換方式

    SpringCloud Config配置中心原理以及環(huán)境切換方式

    這篇文章主要介紹了SpringCloud Config配置中心原理以及環(huán)境切換方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot中Elasticsearch的連接配置原理與使用詳解

    SpringBoot中Elasticsearch的連接配置原理與使用詳解

    Elasticsearch是一種開源的分布式搜索和數(shù)據(jù)分析引擎,它可用于全文搜索、結(jié)構(gòu)化搜索、分析等應(yīng)用場景,本文主要介紹了SpringBoot中Elasticsearch的連接配置原理與使用詳解,感興趣的可以了解一下
    2023-09-09
  • IDEA中Mybatis的MGB使用逆向工程配置的詳細(xì)教程

    IDEA中Mybatis的MGB使用逆向工程配置的詳細(xì)教程

    這篇文章主要介紹了IDEA中Mybatis的MGB使用逆向工程配置,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere

    SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere

    這篇文章主要介紹了SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Spring boot注解@Async線程池實(shí)例詳解

    Spring boot注解@Async線程池實(shí)例詳解

    這篇文章主要介紹了Spring boot注解@Async線程池實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評論

嫩江县| 同德县| 兰州市| 乐业县| 习水县| 赤水市| 炉霍县| 聂拉木县| 建湖县| 徐州市| 晋中市| 霍城县| 呼和浩特市| 珠海市| 望江县| 灵寿县| 札达县| 六盘水市| 宜君县| 南澳县| 大安市| 石屏县| 长葛市| 葵青区| 永仁县| 平顺县| 荔浦县| 榆中县| 山阴县| 连云港市| 岚皋县| 东港市| 邵东县| 宣威市| 吉木萨尔县| 田林县| 三穗县| 雷山县| 淳化县| 宣汉县| 晴隆县|