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


    一.前言

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

    二.基本类型数组的交互

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

    public native double[] arrayAsArgs(int[] a);//求数组的和以及平均数,并以数组的形式返回

      2.native层代码:

    复制代码
    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){
            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函数如下:

    public native String[] quoteArrayAsArgs(String[] s);//从java中传入引用数组到native层,并返回相同的引用数组到java层

      2.native层代码:

    复制代码
    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){//获取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){
            env->SetObjectArrayElement(str2,i,str1[i]);
        }
        return str2;
    }
    复制代码

    四.二维数组的交互

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

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

    public native char[][] twoDimenArrayAsArgs(char[][] c);//原封不动的返回c

      2.native层代码:

    复制代码
    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){
            cc=(jcharArray)env->GetObjectArrayElement(c,i);
            jchar *character=env->GetCharArrayElements(cc, nullptr);
            for(int j=0;j){
                result[i][j]=*(character+j);
            }
            env->ReleaseCharArrayElements(cc,character,0);
        }
        //    for(int i=0;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){
            jcharArray jcharArray=env->NewCharArray(cols);
            env->SetCharArrayRegion(jcharArray,0,cols,result[i]);
            env->SetObjectArrayElement(ret,i,jcharArray);
        }
        return ret;
    }
    复制代码

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

     

     

    我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1zfal74blfdw0

     

  • 相关阅读:
    二十四节气之处暑
    设计模式之门面模式
    限速设计及实现(微服务架构)
    Vue3【二】部分基础难点总结
    HDFS磁盘满额导致Hive写入失败
    【Android进阶】13、对话框
    git 知:提交格式
    23. 合并K个升序链表
    对“不可能三角”发起挑战的公链们
    [附源码]Python计算机毕业设计SSM奖助学金评审系统(程序+LW)
  • 原文地址:https://www.cnblogs.com/luqman/p/array.html