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

Java高級(jí)用法中的JNA類型映射注意細(xì)節(jié)及使用問題

 更新時(shí)間:2022年04月15日 16:08:07   作者:flydean程序那些事  
本文介紹了在使用JNA方法映射中應(yīng)該注意的一些細(xì)節(jié)和具體的使用問題,對(duì)java??JNA類型映射注意細(xì)節(jié)感興趣的朋友一起看看吧

簡(jiǎn)介

JNA提供JAVA類型和native類型的映射關(guān)系,但是這一種映射關(guān)系只是一個(gè)大概的映射,我們?cè)趯?shí)際的應(yīng)用中還有很多需要注意的事項(xiàng),本文將會(huì)為大家詳細(xì)講解在使用類型映射中可能會(huì)出現(xiàn)的問題。一起來看看吧。

String

首先是String的映射,JAVA中的String實(shí)際上對(duì)應(yīng)的是兩種native類型:const char* 和 const wchar_t*。默認(rèn)情況下String會(huì)被轉(zhuǎn)換成為char* 。

char是ANSI類型的數(shù)據(jù)類型,而wchar_t是Unicode字符的數(shù)據(jù)類型,也叫做寬字符。

如果JAVA的unicode characters要轉(zhuǎn)換成為char數(shù)組,那么需要進(jìn)行一些編碼操作,如果設(shè)置了jna.encoding,那么就會(huì)使用設(shè)置好的編碼方式來進(jìn)行編碼。默認(rèn)情況下編碼方式是 “UTF8”.

如果是WString,那么Unicode values可以直接拷貝到WString中,而不需要進(jìn)行任何編碼。

先看一個(gè)簡(jiǎn)單的例子:

char* returnStringArgument(char *arg) {
  return arg;
}

wchar_t* returnWStringArgument(wchar_t *arg) {
  return arg;
}

上面的native代碼可以映射為:

String returnStringArgument(String s);
WString returnWStringArgument(WString s);

再來看一個(gè)不同的例子,假如native方法的定義是這樣的:

int getString(char* buffer, int bufsize);

int getUnicodeString(wchar_t* buffer, int bufsize);

我們定義了兩個(gè)方法,方法的參數(shù)分別是char* 和wchar_t*。

接下來看一下怎么在JAVA中定義方法的映射:

// Mapping A:
int getString(byte[] buf, int bufsize);
// Mapping B:
int getUnicodeString(char[] buf, int bufsize);

下面是具體的使用:

byte[] buf = new byte[256];
int len = getString(buf, buf.length);
String normalCString = Native.toString(buf);
String embeddedNULs = new String(buf, 0, len);

可能有同學(xué)會(huì)問了,既然JAVA中的String可以轉(zhuǎn)換成為char*,為什么這里需要使用byte數(shù)組呢?

這是因?yàn)間etString方法需要對(duì)傳入的char數(shù)組中的內(nèi)容進(jìn)行修改,但是因?yàn)镾tring是不可變的,所以這里是不能直接使用String的,我們需要使用byte數(shù)組。

接著我們使用Native.toString(byte[]) 將byte數(shù)組轉(zhuǎn)換成為JAVA字符串。

再看一個(gè)返回值的情況:

// Example A: Returns a C string directly
const char* getString();
// Example B: Returns a wide character C string directly
const wchar_t* getString();

一般情況下,如果是native方法直接返回string,我們可以使用String進(jìn)行映射:

// Mapping A
String getString();
// Mapping B
WString getString();

如果native code為String分配了內(nèi)存空間,那么我們最好使用JNA中的Pointer作為返回值,這樣我們可以在未來某些時(shí)候,釋放所占用的空間,如下所示:

Pointer getString();

Buffers,Memory,數(shù)組和Pointer

什么時(shí)候需要用到Buffers和Memory呢?

一般情況下如果是基礎(chǔ)數(shù)據(jù)的數(shù)組作為參數(shù)傳到函數(shù)中的話,可以在JAVA中直接使用基礎(chǔ)類的數(shù)組來替代。但是如果native方法在方法返回之后,還需要訪問數(shù)組的話(保存了指向數(shù)組的指針),這種情況下使用基礎(chǔ)類的數(shù)組就不太合適了,這種情況下,我們需要用到ByteBuffers或者M(jìn)emory。

我們知道JAVA中的數(shù)組是帶有長(zhǎng)度的,但是對(duì)于native方法來說,返回的數(shù)組實(shí)際上是一個(gè)指向數(shù)組的指針,我們并不能知道返回?cái)?shù)組的長(zhǎng)度,所以如果native方法返回的是數(shù)組指針的話,JAVA代碼中用數(shù)組來進(jìn)行映射就是不合適的。這種情況下,需要用到Pointer.

Pointer表示的是一個(gè)指針,先看一下Pointer的例子,首先是native代碼:

void* returnPointerArgument(void *arg) {
  return arg;
}

void* returnPointerArrayElement(void* args[], int which) {
  return args[which];
}

接下來是JAVA的映射:

Pointer returnPointerArgument(Pointer p);
Pointer returnPointerArrayElement(Pointer[] args, int which);

除了基本的Pointer之外,你還可以自定義帶類型的Pointer,也就是PointerType. 只需要繼承PointerType即可,如下所示:

public static class TestPointerType extends PointerType {
            public TestPointerType() { }
            public TestPointerType(Pointer p) { super(p); }
        }
TestPointerType returnPointerArrayElement(TestPointerType[] args, int which);

再看一下字符串?dāng)?shù)組:

char* returnStringArrayElement(char* args[], int which) {
  return args[which];
}
wchar_t* returnWideStringArrayElement(wchar_t* args[], int which) {
  return args[which];
}

對(duì)應(yīng)的JAVA映射如下:

String returnStringArrayElement(String[] args, int which);

WString returnWideStringArrayElement(WString[] args, int which);

對(duì)應(yīng)Buffer來說,JAVA NIO中提供了很多類型的buffer,比如ByteBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer和DoubleBuffer等。這里以ByteBuffer為例,來看一下具體的使用.

首先看下native代碼:

int32_t fillInt8Buffer(int8_t *buf, int len, char value) {
  int i;

  for (i=0;i < len;i++) {
    buf[i] = value;
  }
  return len;
}

這里將buff進(jìn)行填充,很明顯后續(xù)還需要使用到這個(gè)buffer,所以這里使用數(shù)組是不合適的,我們可以選擇使用ByteBuffer:

int fillInt8Buffer(ByteBuffer buf, int len, byte value);

然后看下具體怎么使用:

TestLibrary lib = Native.load("testlib", TestLibrary.class);

        ByteBuffer buf  = ByteBuffer.allocate(1024).order(ByteOrder.nativeOrder());
        final byte MAGIC = (byte)0xED;
        lib.fillInt8Buffer(buf, 1024, MAGIC);
        for (int i=0;i < buf.capacity();i++) {
            assertEquals("Bad value at index " + i, MAGIC, buf.get(i));
        }

可變參數(shù)

對(duì)于native和JAVA本身來說,都是支持可變參數(shù)的,我們舉個(gè)例子,在native方法中:

int32_t addVarArgs(const char *fmt, ...) {
  va_list ap;
  int32_t sum = 0;
  va_start(ap, fmt);

  while (*fmt) {
    switch (*fmt++) {
    case 'd':
      sum += va_arg(ap, int32_t);
      break;
    case 'l':
      sum += (int) va_arg(ap, int64_t);
      break;
    case 's': // short (promoted to 'int' when passed through '...') 
    case 'c': // byte/char (promoted to 'int' when passed through '...')
      sum += (int) va_arg(ap, int);
      break;
    case 'f': // float (promoted to ‘double' when passed through ‘...')
    case 'g': // double
      sum += (int) va_arg(ap, double);
      break;
    default:
      break;
    }
  }
  va_end(ap);
  return sum;
}

對(duì)應(yīng)的JAVA方法映射如下:

public int addVarArgs(String fmt, Number... args);

相應(yīng)的調(diào)用代碼如下:

int arg1 = 1;
int arg2 = 2;
assertEquals("32-bit integer varargs not added correctly", arg1 + arg2,
                     lib.addVarArgs("dd", arg1, arg2));

總結(jié)

本文介紹了在使用JNA方法映射中應(yīng)該注意的一些細(xì)節(jié)和具體的使用問題。

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

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

相關(guān)文章

  • 詳解pom.xml中maven profile的激活方式

    詳解pom.xml中maven profile的激活方式

    本文主要介紹了詳解pom.xml中maven profile的激活方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • MyBatis中#{}和${}有哪些區(qū)別

    MyBatis中#{}和${}有哪些區(qū)別

    大家好,本篇文章主要講的是MyBatis中#{}和${}區(qū)別,感興趣的同學(xué)趕快來看一看,對(duì)你有幫助的話記得收藏一下,方向下次瀏覽
    2021-12-12
  • 利用Java對(duì)PDF文件進(jìn)行電子簽章的實(shí)戰(zhàn)過程

    利用Java對(duì)PDF文件進(jìn)行電子簽章的實(shí)戰(zhàn)過程

    隨著電子賬單、回單、通知、合同的流行,電子文檔的可信度變得非常重要,為防止非法篡改,確保文檔的權(quán)威性,我們可以對(duì)PDF進(jìn)行電子簽章,這篇文章主要給大家介紹了關(guān)于如何利用Java對(duì)PDF文件進(jìn)行電子簽章的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • java堆排序概念原理介紹

    java堆排序概念原理介紹

    在本篇文章里我們給大家分享了關(guān)于java堆排序的概念原理相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。
    2018-10-10
  • Spring Data JPA自動(dòng)生成表時(shí)列順序混亂的最新解決辦法

    Spring Data JPA自動(dòng)生成表時(shí)列順序混亂的最新解決辦法

    文章主要介紹了Spring Boot 3.3.5版本中SpringDataJPA自動(dòng)生成表時(shí)列順序混亂的問題,以及如何通過替換Hibernate實(shí)現(xiàn)來解決這個(gè)問題,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java多線程并發(fā)編程 Volatile關(guān)鍵字

    Java多線程并發(fā)編程 Volatile關(guān)鍵字

    volatile 關(guān)鍵字是一個(gè)神秘的關(guān)鍵字,也許在 J2EE 上的 JAVA 程序員會(huì)了解多一點(diǎn),但在 Android 上的 JAVA 程序員大多不了解這個(gè)關(guān)鍵字。只要稍了解不當(dāng)就好容易導(dǎo)致一些并發(fā)上的錯(cuò)誤發(fā)生,例如好多人把 volatile 理解成變量的鎖
    2017-05-05
  • Java關(guān)鍵字instanceof的兩種用法實(shí)例

    Java關(guān)鍵字instanceof的兩種用法實(shí)例

    這篇文章主要介紹了Java關(guān)鍵字instanceof的兩種用法實(shí)例,本文給出了instanceof關(guān)鍵字用于判斷一個(gè)引用類型變量所指向的對(duì)象是否是一個(gè)類(或接口、抽象類、父類)及用于數(shù)組比較,需要的朋友可以參考下
    2015-03-03
  • 運(yùn)行Jar包出現(xiàn)提示xxx中沒有主清單屬性報(bào)錯(cuò)問題解決方法

    運(yùn)行Jar包出現(xiàn)提示xxx中沒有主清單屬性報(bào)錯(cuò)問題解決方法

    這篇文章主要介紹了運(yùn)行Jar包出現(xiàn):xxx中沒有主清單屬性報(bào)錯(cuò),當(dāng)出現(xiàn)報(bào)錯(cuò):xxx中沒有主清單屬性,解決方法也很簡(jiǎn)單,在pom.xml配置中,加上相應(yīng)配置即可,需要的朋友可以參考下
    2023-08-08
  • Java并發(fā) synchronized鎖住的內(nèi)容解析

    Java并發(fā) synchronized鎖住的內(nèi)容解析

    這篇文章主要介紹了Java并發(fā) synchronized鎖住的內(nèi)容解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • java9開始——接口中可以定義private私有方法

    java9開始——接口中可以定義private私有方法

    這篇文章主要介紹了從java9開始 接口中可以定義private私有方法,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-10-10

最新評(píng)論

邻水| 姜堰市| 涡阳县| 阿克陶县| 抚宁县| 巫溪县| 云南省| 云霄县| 延吉市| 日喀则市| 阳信县| 高阳县| 昭觉县| 安远县| 屏南县| 泰州市| 闻喜县| 渭南市| 罗甸县| 监利县| 大丰市| 巴马| 清徐县| 雅安市| 公主岭市| 西丰县| 西乡县| 桐柏县| 枣庄市| 延边| 花莲市| 新竹县| 西安市| 奈曼旗| 宣汉县| 霍州市| 定南县| 普格县| 和静县| 甘孜县| 时尚|