前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JNI编程之java层和native层的数组数据的交互

JNI编程之java层和native层的数组数据的交互

作者头像
故乡的樱花开了
发布2023-10-22 14:10:15
2560
发布2023-10-22 14:10:15
举报
文章被收录于专栏:Android技术专栏

一.前言

  JNI中的数组类型分为基本类型数组和引用类型数组,他们的处理方式是不一样的。基本类型数组中的元素都是jni基本数据类型,可以直接访问;但是引用类型的数组中的元素是一个类的实例,不能直接访问,需要使用jni中的函数进行访问。

二.基本类型数组的交互

  1.java层声明的native函数如下:

代码语言:javascript
复制
public native double[] arrayAsArgs(int[] a);//求数组的和以及平均数,并以数组的形式返回

  2.native层代码:

代码语言:javascript
复制
jdoubleArray native_arrayAsArgs(JNIEnv *env,jobject thiz,jintArray array){
    jint *a=env->GetIntArrayElements(array, nullptr);//获取java层数组的值,并赋给jint*指针变量
    jsize length=env->GetArrayLength(array);//获取java层数组的长度
    jint sum=0;
    jdouble avg=0.0;
    for(int i=0;i<length;i++){
        sum+=*(a+i);//访问每一个数组元素并累加
    }
    avg=(jdouble)sum/length;
    env->ReleaseIntArrayElements(array,a,0);//和GetIntArrayElements()是一对的,使用完之后就要释放内存,防止内存泄漏
    jdouble result[]={(jdouble)sum,avg};
    jdoubleArray result1=env->NewDoubleArray(2);//开辟内存空间,相当于new double[2]
    env->SetDoubleArrayRegion(result1,0,2,result);//给数组赋值
    return result1;
}

 三.引用类型数组的交互

  1.java层声明的native函数如下:

代码语言:javascript
复制
public native String[] quoteArrayAsArgs(String[] s);//从java中传入引用数组到native层,并返回相同的引用数组到java层

  2.native层代码:

代码语言:javascript
复制
jobjectArray native_quoteArrayAsArgs(JNIEnv *env,jobject thiz,jobjectArray s){
    jclass clazz=env->FindClass("java/lang/String");
    jsize length=env->GetArrayLength(s);
    jstring str;
    jstring str1[length];
    for(int i=0;i<length;i++){//获取java层引用数组中每个元素的值,并存储在str1数组中
        str=(jstring)env->GetObjectArrayElement(s,i);
        str1[i]=str;
    }
    jobjectArray str2;
    str2=env->NewObjectArray(length,clazz, nullptr);//为引用数组开辟内存,相当于new String[length]
    for(int i=0;i<length;i++){
        env->SetObjectArrayElement(str2,i,str1[i]);
    }
    return str2;
}

四.二维数组的交互

  二维数组可以看作特殊的一维数组,数组中的每个元素的类型是一维数组,也就是说每个元素是一个引用类型的数据,这样理解之后,代码就好写了。

  1.java层声明的native函数如下:

代码语言:javascript
复制
public native char[][] twoDimenArrayAsArgs(char[][] c);//原封不动的返回c

  2.native层代码:

代码语言:javascript
复制
jobjectArray native_towDimenArrayAsArgs(JNIEnv *env,jobject thiz,jobjectArray c){
    jsize rows=env->GetArrayLength(c);//获取行数
    jcharArray cc=(jcharArray)env->GetObjectArrayElement(c,0);
    jsize cols=env->GetArrayLength(cc);//获取列数
    jchar result[rows][cols];
    for(int i=0;i<rows;i++){
        cc=(jcharArray)env->GetObjectArrayElement(c,i);
        jchar *character=env->GetCharArrayElements(cc, nullptr);
        for(int j=0;j<cols;j++){
            result[i][j]=*(character+j);
        }
        env->ReleaseCharArrayElements(cc,character,0);
    }
    //    for(int i=0;i<rows;i++){//方式二:赋值,不会申请内存
    //        cc=(jcharArray)env->GetObjectArrayElement(c,i);
    //        env->GetCharArrayRegion(cc,0,cols,result[i]);
    //    }
    jclass clazz=env->FindClass("[C");//char[]的Class对象
    jobjectArray ret=env->NewObjectArray(rows,clazz, nullptr);
    for(int i=0;i<rows;i++){
        jcharArray jcharArray=env->NewCharArray(cols);
        env->SetCharArrayRegion(jcharArray,0,cols,result[i]);
        env->SetObjectArrayElement(ret,i,jcharArray);
    }
    return ret;
}

  如果是其他类型的数组,将类型换成其他类型即可,代码不用变。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档