JNI 函數(五)數組操作


JNI 函數(五)數組操作

(一)、獲取數組的長度

函數原型:jsize GetArrayLength(JNIEnv *env, jarray array)

  返回數組的長度

  參數:

    env:JNI 接口指針

    array:Java 數組

  返回:

    數組的長度

(二)、創建對象數組

函數原型:jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement);

  創建一個新的對象數組,它的元素的類型是 elementClass,並且所有元素的默認值是 initialElement

  參數:

    env:JNI 接口指針

    length:數組大小

    elementClass:數組元素類

    initialElement:數組元素的初始值

  返回:

    Java 數組對象,如果無法構造數組,則返回 NULL

  異常:

    如果內存不足,則拋出 OutOfMemoryError

(三)、獲取數組元中的某個元素

函數原型:jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index);

  返回元素中某個位置的元素

  參數:

    env:JNI 接口指針

    array:Java 數組

    index:數組下標

  返回:

    Java 對象

  異常:

    如果index下標不是一個有效的下標,則會拋出 ArrayIndexOutOfBoundsException

(四)、設置數組中某個元素的值

函數原型:void SetObjectArrayElement(JNIEnv *env,jobjectArray array,jsize index,jobject value);

  設置下標為 index 元素的值。

  參數:

    env:JNI 接口指針

    array:Java 數組

    index:數組下標

    value:數組元素的新值

  異常:

    如果 index 不是有效下標,則會拋出 ArrayIndexOutOfBoundsException

    如果 value 不是元素類的子類,則會拋出 ArrayStoreException

(五)、創建基本類型數組系列

通用函數類型:ArrayType New<PrimitiveType>Array(JNIEnv *env, jsize length);

  用於構造基本類型數組對象的一系列操作。下面說明了特定基本類型數組的創建函數。可以把 New<PrimitiveType>Array 替換為某個實際的基本類型數組創建函數 ,然后將 ArrayType 替換為相應的數組類型

New<PrimitiveType>Array Routines Array Type
NewBooleanArray() jbooleanArray
NewByteArray() jbyteArray
NewCharArray() jcharArray
NewShortArray() jshortArray
NewIntArray() jintArray
NewLongArray() jlongArray
NewFloatArray() jfloatArray
NewDoubleArray() jdoubleArray

  參數:

    env:JNI 接口指針

    length:數組長度

  返回:

    Java 數組,如果無法創建該數組,則返回 NULL。

(六)、獲取基本類型數組的中數組指針系列

通用函數類型:NativeType * Get<PrimitiveType>ArrayElements(JNIEnv *env, ArrayType array, jboolean * isCopy);

  一組返回類型是基本類型的數組指針。在調用相應的 Release<PrimitiveType>ArrayElements() 函數前將一直有效。由於返回的數組可能是 Java 數組的副本,因此,對返回數組的變更沒有在基本類型中反應出來。除非了調用了一組返回基本類型數組體的函數。結果在調用相應的 Release<PrimitiveType>ArrayElements() 函數前將一直有效。由於返回的數組可能是 Java 數組的副本,因此對返回數組的更改不必在基本類型數組中反映出來,直到調用 “ Release<PrimitiveType>ArrayElements() ” 函數。

  如果 isCopy 不是 NULL,*isCopy 在復制完成后即被設為 JNI_TRUE 。如果未復制,則設為 JNI_FALSE。

  下面說明了特定的基本類型數組元素的具體函數:

  1. Get<PrimitiveType>ArrayElements 替換為表中某個實際的基本> 類型的函數
  2. 將 ArrayType 替換為對應的數組類型
  3. 將 NativeType 替換為本地變量

  不管布爾數組在 Java 虛擬機總如何表示,GetBooleanArrayElements() 將始終返回一個 jboolean 類型的指針,其中每一個字節代表一個元素(開包表示)。內存中將確保所有其他類型的數組為連續的。

Get<PrimitiveType>ArrayElements Routines Array Type Native Type
GetBooleanArrayElements() jbooleanArray jboolean
GetByteArrayElements() jbyteArray jbyte
GetCharArrayElements() jcharArray jchar
GetShortArrayElements() jshortArray jshort
GetIntArrayElements() jintArray jint
GetLongArrayElements() jlongArray jlong
GetFloatArrayElements() jfloatArray jfloat
GetDoubleArrayElements() jdoubleArray jdouble

  參數:

    env:JNI 接口指針

    array:Java 數組

    isCopy:指向布爾值的指針

  返回:

    返回指向數組元素的指針,如果操作失敗,則返回 NULL

(七)、釋放基本類型的數組系列

通用函數原型:void Release<PrimitiveType>ArrayElements(JNIEnv *env, ArrayType array, NativeType *elems, jint mode);

  通知虛擬機 Native 不再訪問數組的元素了。elems 參數是使用相應的 Get <PrimitiveType> ArrayElements() 函數數組返回的指針。如果有需要的話,該函數復制復制所有的 elems 上的變換到原始數組元素上去。mode 參數提供了數組 buffer 應該怎么被釋放。如果elems 不是 array 的一個副本,mode 並沒有什么影響。

  mode 的取值 有如下 3 種情況:

  1. 0:復制內容並釋放 elems 緩沖區
  2. JNI_COMMIT:復制內容但不釋放 elems 緩沖區
  3. JNI_ABORT:釋放緩沖區而不復制可能的更改

  大多數情況下,程序員將 “0” 作為參數傳遞,因為這樣可以確保固定和復制數組的一致行為。其他選項可以讓程序員更好的控制內存。

  下面說明了特定的基本類型數組元素的具體函數:

  1. Release <PrimitiveType> ArrayElements 替換下面中某個實際的基本> 類型的函數
  2. 將 ArrayType 替換為對應的基本數組類型
  3. 將 NativeType 替換為本地變量

    下面描述了基本類型數組釋放的詳情。 您應該進行以下替換:

Release<PrimitiveType>ArrayElements Routines Array Type Native Type
ReleaseBooleanArrayElements() jbooleanArray jboolean
ReleaseByteArrayElements() jbyteArray jbyte
ReleaseCharArrayElements() jcharArray jchar
ReleaseShortArrayElements() jshortArray jshort
ReleaseIntArrayElements() jintArray jint
ReleaseLongArrayElements() jlongArray jlong
ReleaseFloatArrayElements() jfloatArray jfloat
ReleaseDoubleArrayElements() jdoubleArray jdouble

  參數:

    env:JNI 接口指針

    array:Java 數組

    elems:指向基本類型的數組的指針

    mode:釋放模式

(8)、將基本類型數組某一區域復制到緩沖區中

函數原型:Get<PrimitiveType> ArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf);

  復制基本類型的數組給 buff

  下面說明了特定的基本類型數組元素的具體函數:

  1. 將 Get<PrimitiveType> ArrayRegion 替換下面中某個實際的基本> 類型的函數
  2. 將 ArrayType 替換為對應的基本數組類型
  3. 將 NativeType 替換為本地變量
Get<PrimitiveType>ArrayRegion Routine Array Type Native Type
GetBooleanArrayRegion() jbooleanArray jboolean
GetByteArrayRegion() jbyteArray jbyte
GetCharArrayRegion() jcharArray jchar
GetShortArrayRegion() jshortArray jshort
GetIntArrayRegion() jintArray jint
GetLongArrayRegion() jlongArray jlong
GetFloatArrayRegion() jfloatArray jfloat
GetDoubleArrayRegion() jdoubleArray jdouble

  參數:

    env:JNI 接口指針

    array:Java 數組

    start:開始索引

    len:需要復制的長度

    buf:目標 buffer

  異常:

    如果索引無效,則拋出 ArrayIndexOutOfBoundsException

(九)、基本類型數組的某一區域從緩沖區中復制回來

函數原型:void Set<PrimitiveType> ArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize len, const NativeType *buf);

  主要是沖緩沖區復制基本類型的數組的函數

  下面說明了特定的基本類型數組元素的具體函數:

  1. Set<PrimitiveType>ArrayRegion 替換下面中某個實際的基本> 類型的函數
  2. 將 ArrayType 替換為對應的基本數組類型
  3. 將 NativeType 替換為本地變量
Set<PrimitiveType>ArrayRegion Routine Array Type Native Type
SetBooleanArrayRegion() jbooleanArray jboolean
SetByteArrayRegion() jbyteArray jbyte
SetCharArrayRegion() jcharArray jchar
SetShortArrayRegion() jshortArray jshort
SetIntArrayRegion() jintArray jint
SetLongArrayRegion() jlongArray jlong
SetFloatArrayRegion() jfloatArray jfloat
SetDoubleArrayRegion() jdoubleArray jdouble

  參數:

    env:JNI 接口指針

    array:Java 數組

    start:開始索引

    len:需要復制的長度

    buf:源 buffer

  異常:

    如果索引無效則會拋出 ArrayIndexOutOfBoundsException

(十)、補充

  從 JDK/JER 1.1 開始提供 Get/Release<primitivetype>ArrayElements 函數獲取指向原始數組元素的指針。如果 VM 支持鎖定,則返回指向原始數組的指針,否則,復制。

  從 JDK/JRE 1.3 開始引入新的功能即便 VM 不支持鎖定,本地代碼也可以獲取數組元素的直接指針,

函數原型:void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);

函數原型:void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);

  雖然這兩個函數與上面的 Get/Release <primitivetype> ArrayElements 函數很像,但是在使用這個功能的時候,還是有很多的限制。

  在調用 GetPrimitiveArrayCritical 之后,調用 ReleasePrimitiveArrayCritical 之前,這個區域是不能調用其他 JNI 函數,而且也不能調用任何可能導致線程阻塞並等待另一個 Java 線程的系統調用。

  比如,當前線程不能調用 read 函數來讀取,正在被其他所寫入的 stream。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM