c++ java setobjectarrayelement_Java中JNI的使用詳解第五篇:C/C++中操作Java中的數組
发布日期:2021-08-19 23:05:01 浏览次数:19 分类:技术文章

本文共 4025 字,大约阅读时间需要 13 分钟。

在Java中數組分為兩種:

1.基本類型數組

2.對象類型(Object[])的數組(數組中存放的是指向Java對象中的引用)

一個能通用於兩種不同類型數組的函數:

GetArrayLength(jarray array);

首先來看一下怎么處理基本類型的數組:

(1) GetArrayElements(Array arr , jboolean* isCopide);

這類函數可以把Java基本類型的數組轉換到C/C++中的數組,有兩種處理方式,一種是拷貝一份傳回本地代碼,另一個是把指向Java數組的指針直接傳回到本地代碼中,處理完本地化的數組后,通過ReleaseArrayElements來釋放數組

(2) ReleaseArrayElements(Array arr , * array , jint mode)

用這個函數可以選擇將如何處理Java跟C++的數組,是提交,還是撤銷等,內存釋放還是不釋放等

mode可以取下面的值:

0 :對Java的數組進行更新並釋放C/C++的數組

JNI_COMMIT :對Java的數組進行更新但是不釋放C/C++的數組

JNI_ABORT:對Java的數組不進行更新,釋放C/C++的數組

(3) GetPrimittiveArrayCritical(jarray arr , jboolean* isCopied);

(4) ReleasePrimitiveArrayCritical(jarray arr , void* array , jint mode);

也是JDK1.2出來的,為了增加直接傳回指向Java數組的指針而加入的函數,同樣的也會有同GetStringCritical的死鎖的問題

(5) GetArrayRegion(Array arr , jsize start , jsize len , * buffer);

在C/C++預先開辟一段內存,然后把Java基本類型的數組拷貝到這段內存中,這個方法和之前拷貝字符串的GetStringRegion方法的原理是類似的

(6) SetArrayRegion(Array arr , jsize start , jsize len , const * buffer);

把Java基本類型的數組中的指定范圍的元素用C/C++的數組中的元素來賦值

(7) Array NewArray(jsize sz)

指定一個長度然后返回相應的Java基本類型的數組

在來看一下怎么處理對象型數組

JNI沒有提供直接把Java的對象類型數組(Object[])直接轉到C++中的Object[]數組的函數,而是直接通過Get/SetObjectArrayElement這樣的函數來對Java的Object[]數組進行操作由於去的對象數組沒有進行拷貝,所以不需要釋放任何資源

NewObjectArray可以通過指定長度跟初始值來創建某個類的數組

下面來看一下例子:操作兩種類型的數組

Java中的代碼:

packagecom.jni.demo;

publicclassJNIDemo {

//定義一個int型數組

int[] arrays = {4,3,12,56,1,23,45,67};

//定義Father對象數組

Father[] objArrays = {newFather(),newFather(),newFather()};

//定義一個本地方法

publicnativevoidcallCppFunction();

publicstaticvoidmain(String[] args)throwsException{

//調用動態鏈接庫

System.loadLibrary("JNIDemo");

JNIDemo jniDemo = newJNIDemo();

jniDemo.callCppFunction();

}

}

C++中的代碼:

#include

#include"com_jni_demo_JNIDemo.h"

#include

usingnamespacestd;

JNIEXPORT voidJNICALL Java_com_jni_demo_JNIDemo_callCppFunction (JNIEnv * env, jobject obj)

{

//獲取Java中數組屬性arrays的id

jfieldID fid_arrays = env->GetFieldID(env->GetObjectClass(obj),"arrays","[I");

//獲取Java中數組屬性arrays的對象

jintArray jint_arr = (jintArray)env->GetObjectField(obj,fid_arrays);

//獲取arrays對象的指針

jint* int_arr = env->GetIntArrayElements(jint_arr,NULL);

//獲取數組的長度

jsize len = env->GetArrayLength(jint_arr);

//打印數組中的值

cout<

for(ints =0;s

cout<

}

cout<

//新建一個jintArray對象

jintArray jint_arr_temp = env->NewIntArray(len);

//獲取jint_arr_temp對象的指針

jint* int_arr_temp = env->GetIntArrayElements(jint_arr_temp,NULL);

//計數

jint count = 0;

//偶數位存入到int_arr_temp內存中

for(jsize j=0;j

if(j%2==0){

int_arr_temp[count++] = int_arr[j];

}

}

//打印int_arr_temp內存中的數組

cout<

for(jsize k=0;k

cout<

}

cout<

//將數組中一段(0-2)數據拷貝到內存中,並且打印出來

jint* buffer = newjint[len];

//獲取數組中從0開始長度為3的一段數據值

env->GetIntArrayRegion(jint_arr,0,3,buffer);

cout<

for(intl=0;l<3;l++){

cout<

}

cout<

//將數組中的一段(3-7)設置成一定的值,並且打印出來

jint* buffers = newjint[4];

for(intn=0;n<4;n++){

buffers[n] = n+1;

}

//將buffers這個數組中值設置到數組從3開始長度是4的值中

env->SetIntArrayRegion(jint_arr,3,4,buffers);

//從新獲取數組指針

int_arr = env->GetIntArrayElements(jint_arr,NULL);

cout<

for(intm=0;m

cout<

}

cout<

//調用C++標准庫中的排序方法sort(...),傳遞一個數組的開始指針和結束指針

std::sort(int_arr,int_arr+len);

//迭代打印數組中的元素

cout<

for(jsize i=0;i

cout<

}

cout<

//釋放數組指針

env->ReleaseIntArrayElements(jint_arr,int_arr,JNI_ABORT);

//獲取Java中對象Father數組屬性的id

jfieldID fid_obj_arrays = env->GetFieldID(env->GetObjectClass(obj),"objArrays","[Lcom/jni/demo/Father;");

//獲取Java中對象數組Father屬性objArrays的對象

jobjectArray jobj_arr = (jobjectArray)env->GetObjectField(obj,fid_obj_arrays);

//從對象數組中獲取索引值為1的對象Father

jobject jobj = env->GetObjectArrayElement(jobj_arr,1);

//獲取Father對象的class對象

jclass clazz_father = env->GetObjectClass(jobj);

//獲取Father對象中的function方法的id

jmethodID id_father_function = env->GetMethodID(clazz_father,"function","()V");

//調用Father對象中的function方法

env->CallVoidMethod(jobj,id_father_function);

//在本地創建一個大小為10的對象數組,對象的初始化都是jobj,也就是方法的第三個參數

jobjectArray jobj_arr_temp = env->NewObjectArray(10,env->GetObjectClass(jobj),jobj);

//獲取本地對象數組中第4個對象

jobject jobj_temp = env->GetObjectArrayElement(jobj_arr_temp,3);

//調用Father對象中的function方法

env->CallVoidMethod(jobj_temp,id_father_function);

}

在Eclipse編譯運行結果如下:

edb70e2f28dff31f7825e0387265bb37.jpe

不要以為這就結束了,后面還有很多內容呀!

转载地址:https://blog.csdn.net/weixin_31068553/article/details/114947234 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:php销毁变量,PHP变量的定义、可变变量、变量引用、销毁方法
下一篇:java已启动但返回退出代码_Eclipse返回错误消息“Java已启动但返回退出代码= 1”...

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年12月30日 20时43分01秒