为了账号安全,请及时绑定邮箱和手机立即绑定

如何将数组从JNI返回到Java?

如何将数组从JNI返回到Java?

慕容森 2019-10-06 16:07:44
我正在尝试使用android NDK。有没有办法将int[]在JNI中创建的数组(以我的情况为例)返回给Java?如果是这样,请提供一个可以执行此操作的JNI函数的简单示例。-谢谢
查看完整描述

3 回答

?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

如果您已经阅读了文档,但仍然有一些问题应作为最初问题的一部分。在这种情况下,示例中的JNI函数将创建多个数组。外部数组由使用JNI函数创建的“对象”数组组成NewObjectArray()。从JNI的角度来看,这就是一个二维数组,一个包含多个其他内部数组的对象数组。


以下for循环使用JNI函数创建类型为int []的内部数组NewIntArray()。如果您只想返回一个一维整数数组,则NewIntArray()可以使用该函数来创建返回值。如果要创建字符串的一维数组,则可以使用该NewObjectArray()函数,但为该类使用不同的参数。


由于您要返回一个int数组,因此您的代码将如下所示:


JNIEXPORT jintArray JNICALL Java_ArrayTest_initIntArray(JNIEnv *env, jclass cls, int size)

{

 jintArray result;

 result = (*env)->NewIntArray(env, size);

 if (result == NULL) {

     return NULL; /* out of memory error thrown */

 }

 int i;

 // fill a temp structure to use to populate the java int array

 jint fill[size];

 for (i = 0; i < size; i++) {

     fill[i] = 0; // put whatever logic you want to populate the values here.

 }

 // move from the temp structure to the java structure

 (*env)->SetIntArrayRegion(env, result, 0, size, fill);

 return result;

}


查看完整回答
反对 回复 2019-10-06
?
偶然的你

TA贡献1841条经验 获得超3个赞

基于提出的问题,这已经在第一个答案中得到了解释,即如何通过jobjectArray传递int []。但是这是一个示例,我们如何返回包含数据列表的jobjectArray。例如,这在某些情况下很有用:当某人需要返回2D格式的数据以绘制带有x和y点的线时。以下示例显示jobjectArray如何以以下格式的形式返回数据:


Java输入到JNI:

Array [ Arraylistof x float points] [ Arraylistof y float points]


JNI输出到Java:

jobjectArray[ Arraylist个x浮点数] [ Arraylist个y浮点数]


    extern "C" JNIEXPORT jobjectArray JNICALL

        _MainActivity_callOpenCVFn(

                JNIEnv *env, jobject /* this */,

                jobjectArray list) {


         //Finding arrayList class and float class(2 lists , one x and another is y)

            static jclass arrayListCls = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));

            jclass floatCls = env->FindClass("java/lang/Float");

         //env initialization of list object and float

            static jmethodID listConstructor = env->GetMethodID(arrayListCls, "<init>", "(I)V");

            jmethodID alGetId  = env->GetMethodID(arrayListCls, "get", "(I)Ljava/lang/Object;");

            jmethodID alSizeId = env->GetMethodID(arrayListCls, "size", "()I");

            static jmethodID addElementToList = env->GetMethodID(arrayListCls, "add", "(Ljava/lang/Object;)Z");


            jmethodID floatConstructor = env->GetMethodID( floatCls, "<init>", "(F)V");

            jmethodID floatId = env->GetMethodID(floatCls,"floatValue", "()F");



        //null check(if null then return)

        if (arrayListCls == nullptr || floatCls == nullptr) {

            return 0;

        }


    //     Get the value of each Float list object in the array

        jsize length = env->GetArrayLength(list);


        //If empty

        if (length < 1) {

            env->DeleteLocalRef(arrayListCls);

            env->DeleteLocalRef(floatCls);

            return 0;

        }


// Creating an output jObjectArray

    jobjectArray outJNIArray = env->NewObjectArray(length, arrayListCls, 0);


        //taking list of X and Y points object at the time of return

        jobject  xPoint,yPoint,xReturnObject,yReturnObject;


            //getting the xList,yList object from the array

            jobject xObjFloatList = env->GetObjectArrayElement(list, 0);

            jobject yObjFloatList = env->GetObjectArrayElement(list, 1);



     // number of elements present in the array object

        int xPointCounts = static_cast<int>(env->CallIntMethod(xObjFloatList, alSizeId));


        static jfloat xReturn, yReturn;

                jobject xReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);

        jobject yReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);


    for (int j = 0; j < xPointCounts; j++) {

            //Getting the x points from the x object list in the array

            xPoint = env->CallObjectMethod(xObjFloatList, alGetId, j);

            //Getting the y points from the y object list in the array

            yPoint = env->CallObjectMethod(yObjFloatList, alGetId, j);


//Returning jobjectArray(Here I am returning the same x and points I am receiving from java side, just to show how to make the returning `jobjectArray`)  


            //float x and y values

            xReturn =static_cast<jfloat >(env->CallFloatMethod(xPoint, floatId,j));

            yReturn =static_cast<jfloat >(env->CallFloatMethod(yPoint, floatId,j));



            xReturnObject = env->NewObject(floatCls,floatConstructor,xReturn);

             yReturnObject = env->NewObject(floatCls,floatConstructor,yReturn);


            env->CallBooleanMethod(xReturnArrayList,addElementToList,xReturnObject);



            env->CallBooleanMethod(yReturnArrayList,addElementToList,yReturnObject);

            env->SetObjectArrayElement(outJNIArray,0,xReturnArrayList);

            env->SetObjectArrayElement(outJNIArray,1,yReturnArrayList);

        __android_log_print(ANDROID_LOG_ERROR, "List of X and Y are saved in the array","%d", 3);


    }


    return outJNIArray;


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 2480 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信