欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java高級(jí)用法之JNA中使用類型映射

 更新時(shí)間:2022年03月30日 10:58:47   作者:程序那些事  
JNA中有很多種映射,本文主要介紹了java高級(jí)用法之JNA中使用類型映射,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

簡介

JNA中有很多種映射,library的映射,函數(shù)的映射還有函數(shù)參數(shù)和返回值的映射,libary和函數(shù)的映射比較簡單,我們?cè)谥暗奈恼轮幸呀?jīng)講解過了,對(duì)于類型映射來說,因?yàn)镴AVA中的類型種類比較多,所以這里我們將JNA的類型映射提取出來單獨(dú)講解。

類型映射的本質(zhì)

我們之前提到在JNA中有兩種方法來映射JAVA中的方法和native libary中的方法,一種方法叫做interface mapping,一種方式叫做direct mapping。

但是我們有沒有考慮過這兩種映射的本質(zhì)是什么呢?

比如native有一個(gè)方法,我們是如何將JAVA代碼中的方法參數(shù)傳遞給native方法,并且將native方法的返回值轉(zhuǎn)換成JAVA中函數(shù)的返回類型呢?

答案就是序列化。

因?yàn)楸举|(zhì)上一切的交互都是二進(jìn)制的交互。JAVA類型和native類型進(jìn)行轉(zhuǎn)換,最簡單的情況就是JAVA類型和native類型底層的數(shù)據(jù)長度保持一致,這樣在進(jìn)行數(shù)據(jù)轉(zhuǎn)換的時(shí)候就會(huì)更加簡單。

我們看下JAVA類型和native類型的映射和長度關(guān)系:

C TypeNative類型的含義Java Type
char8-bit整型byte
wchar_t和平臺(tái)相關(guān)char
short16-bit整型short
int32-bit整型int
intboolean flagboolean
enum枚舉類型int (usually)
long long, __int6464-bit整型long
float32-bit浮點(diǎn)數(shù)float
double64-bit浮點(diǎn)數(shù)double
pointer (e.g. void*)平臺(tái)相關(guān)Buffer Pointer
pointer (e.g. void*), array平臺(tái)相關(guān)

[] (原始類型數(shù)組)

上面的JAVA類型都是JDK自帶的類型(Pointer除外)。

除了JAVA自帶的類型映射,JNA內(nèi)部也定義了一些數(shù)據(jù)類型,可以跟native的類型進(jìn)行映射:

C TypeNative類型的含義Java Type
long和平臺(tái)相關(guān)(32- or 64-bit integer)NativeLong
const char*字符串 (native encoding or jna.encoding)String
const wchar_t*字符串 (unicode)WString
char**字符串?dāng)?shù)組String[]
wchar_t**字符串?dāng)?shù)組(unicode)WString[]
void**pointers數(shù)組Pointer[]
struct* struct結(jié)構(gòu)體指針和結(jié)構(gòu)體Structure
union結(jié)構(gòu)體Union
struct[]結(jié)構(gòu)體數(shù)組Structure[]
void (*FP)()函數(shù)指針 (Java or native)Callback
pointer ( *)指針PointerType
other整數(shù)類型IntegerType
other自定義映射類型NativeMapped

TypeMapper

除了定義好的映射關(guān)系之外,大家也可以使用TypeMapper來對(duì)參數(shù)類型進(jìn)行自定義轉(zhuǎn)換,先來看下TypeMapper的定義:

public interface TypeMapper {

    FromNativeConverter getFromNativeConverter(Class<?> javaType);

    ToNativeConverter getToNativeConverter(Class<?> javaType);
}

TypeMapper是一個(gè)interface,它定義了兩個(gè)converter方法,分別是getFromNativeConverter和getToNativeConverter。

如果要使用TypeMapper則需要實(shí)現(xiàn)它而這兩個(gè)方法即可。我們看一下官方的W32APITypeMapper是怎么實(shí)現(xiàn)的:

 TypeConverter stringConverter = new TypeConverter() {
                @Override
                public Object toNative(Object value, ToNativeContext context) {
                    if (value == null)
                        return null;
                    if (value instanceof String[]) {
                        return new StringArray((String[])value, true);
                    }
                    return new WString(value.toString());
                }
                @Override
                public Object fromNative(Object value, FromNativeContext context) {
                    if (value == null)
                        return null;
                    return value.toString();
                }
                @Override
                public Class<?> nativeType() {
                    return WString.class;
                }
            };
            addTypeConverter(String.class, stringConverter);
            addToNativeConverter(String[].class, stringConverter);

首先定義一個(gè)TypeConverter,在TypeConverter中實(shí)現(xiàn)了toNative,fromNative和nativeType三個(gè)方法。在這個(gè)例子中,native type是WString,而JAVA type是String。而這個(gè)TypeConverter就是最終要使用的FromNativeConverter和ToNativeConverter。

有了typeMapper,應(yīng)該怎么使用呢?最簡單的方法就是將其添加到Native.load的第三個(gè)參數(shù)中,如下所示:

 TestLibrary lib = Native.load("testlib", TestLibrary.class, Collections.singletonMap(Library.OPTION_TYPE_MAPPER, mapper));

NativeMapped

TypeMapper需要在調(diào)用Native.load方法的時(shí)候傳入,從而提供JAVA類型和native類型的轉(zhuǎn)換關(guān)系。TypeMapper可以看做是類型轉(zhuǎn)換關(guān)系的外部維護(hù)者。

可能很多朋友已經(jīng)想到了,既然能在JAVA類型外部維護(hù)轉(zhuǎn)換關(guān)系,那么可不可以在JAVA類型本身對(duì)這個(gè)轉(zhuǎn)換關(guān)系進(jìn)行維護(hù)呢?答案是肯定的,我們只需要在要實(shí)現(xiàn)轉(zhuǎn)換類型關(guān)系的JAVA類型實(shí)現(xiàn)NativeMapped接口即可。

先來看下NativeMapped接口的定義:

public interface NativeMapped {

    Object fromNative(Object nativeValue, FromNativeContext context);

    Object toNative();

    Class<?> nativeType();
}

可以看到NativeMapped中定義要實(shí)現(xiàn)的方法基本上和FromNativeConverter、ToNativeConverter中定義的方法一致。

下面舉一個(gè)具體的例子來說明一下NativeMapped到底應(yīng)該怎么使用。首先我們定義一個(gè)enum類實(shí)現(xiàn)NativeMapped接口:

    public enum TestEnum implements NativeMapped {
        VALUE1, VALUE2;

        @Override
        public Object fromNative(Object nativeValue, FromNativeContext context) {
            return values()[(Integer) nativeValue];
        }

        @Override
        public Object toNative() {
            return ordinal();
        }

        @Override
        public Class<?> nativeType() {
            return Integer.class;
        }
    }

這個(gè)類實(shí)現(xiàn)了從Integer到TestEnum枚舉的轉(zhuǎn)換。

要想使用該TestEnum類的話,需要定義一個(gè)interface:

    public static interface EnumerationTestLibrary extends Library {
        TestEnum returnInt32Argument(TestEnum arg);
    }

具體調(diào)用邏輯如下:

EnumerationTestLibrary lib = Native.load("testlib", EnumerationTestLibrary.class);
assertEquals("Enumeration improperly converted", TestEnum.VALUE1, lib.returnInt32Argument(TestEnum.VALUE1));
assertEquals("Enumeration improperly converted", TestEnum.VALUE2, lib.returnInt32Argument(TestEnum.VALUE2));

可以看到,因?yàn)镹ativeMapped中已經(jīng)包含了類型轉(zhuǎn)換的信息,所以不需要再指定TypeMapper了。

注意,這里用到了testlib,這個(gè)testlib是從JNA的native模塊中編譯出來的,如果你是MAC環(huán)境的話可以拷貝JNA代碼,運(yùn)行ant native即可得到,編譯完成之后,將這個(gè)libtestlib.dylib拷貝到你項(xiàng)目中的resources目錄下面darwin-aarch64或者darwin-x86即可。

有不會(huì)的同學(xué),可以聯(lián)系我。

總結(jié)

本文講解了JNA中的類型映射規(guī)則和自定義類型映射的方法。

本文的代碼:https://github.com/ddean2009/learn-java-base-9-to-20

到此這篇關(guān)于java高級(jí)用法之JNA中使用類型映射的文章就介紹到這了,更多相關(guān)JNA 類型映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java使用Cipher類實(shí)現(xiàn)加密的過程詳解

    Java使用Cipher類實(shí)現(xiàn)加密的過程詳解

    這篇文章主要介紹了Java使用Cipher類實(shí)現(xiàn)加密的過程詳解,Cipher類提供了加密和解密的功能,創(chuàng)建密匙主要使用SecretKeySpec、KeyGenerator和KeyPairGenerator三個(gè)類來創(chuàng)建密匙。感興趣可以了解一下
    2020-07-07
  • 淺談Java多線程實(shí)現(xiàn)及同步互斥通訊

    淺談Java多線程實(shí)現(xiàn)及同步互斥通訊

    下面小編就為大家?guī)硪黄獪\談Java多線程實(shí)現(xiàn)及同步互斥通訊。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • 關(guān)于@Entity和@Table注解的用法詳解

    關(guān)于@Entity和@Table注解的用法詳解

    這篇文章主要介紹了關(guān)于@Entity和@Table注解的用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 基于RestTemplate的使用方法(詳解)

    基于RestTemplate的使用方法(詳解)

    下面小編就為大家?guī)硪黄赗estTemplate的使用方法(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • java繼承學(xué)習(xí)之super的用法解析

    java繼承學(xué)習(xí)之super的用法解析

    本文介紹java繼承super的用法,Java繼承是會(huì)用已存在的類的定義作為基礎(chǔ)建立新類的技術(shù)新類的定義可以增加新的數(shù)據(jù)或者新的功能,也可以使用父類的功能,但不能選擇性的繼承父類 這種繼承使得復(fù)用以前的代碼非常容易,能夠大大的縮短開發(fā)的周期,需要的朋友可以參考下
    2022-02-02
  • 關(guān)于Java中的dozer對(duì)象轉(zhuǎn)換問題

    關(guān)于Java中的dozer對(duì)象轉(zhuǎn)換問題

    Dozer是Java?Bean到Java?Bean映射器,它以遞歸方式將數(shù)據(jù)從一個(gè)對(duì)象復(fù)制到另一個(gè)對(duì)象,這篇文章主要介紹了Java中的dozer對(duì)象轉(zhuǎn)換的操作方法,需要的朋友可以參考下
    2022-08-08
  • Java利用IO流實(shí)現(xiàn)簡易的記事本功能

    Java利用IO流實(shí)現(xiàn)簡易的記事本功能

    本文將利用Java中IO流編寫一個(gè)模擬日記本的程序,通過在控制臺(tái)輸入指令,實(shí)現(xiàn)在本地新建文件,打開日記本和修改日記本等功能,感興趣的可以了解一下
    2022-05-05
  • 深入了解Java ServletContext

    深入了解Java ServletContext

    這篇文章主要介紹了Java ServletContext的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • Java實(shí)現(xiàn)圖片切割功能

    Java實(shí)現(xiàn)圖片切割功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖片切割功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • java實(shí)戰(zhàn)之猜字小游戲

    java實(shí)戰(zhàn)之猜字小游戲

    這篇文章主要介紹了java實(shí)戰(zhàn)之猜字小游戲,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助呦,需要的朋友可以參考下
    2021-04-04

最新評(píng)論