Return a 2D primitive array from C to Java from JNI/NDK

后端 未结 3 1972
暖寄归人
暖寄归人 2020-12-16 03:21

I have found large amounts of documentation on how to generate a 2D primitive array in JNI and returning it to Java. But these pieces of information fail to describe how to

相关标签:
3条回答
  • 2020-12-16 03:33

    Thanks Timo for your help and link. For posterity, I'm adding a complete code set that would go through the process of generating a 2D primitive array consumable by Java, from an existing C 2D primitive array.

    // Returns a 2D float array from C to Java
    jobjectArray ndk_test_getMy2DArray(JNIEnv* env, jobject thiz, jlong context)
    {
        // Cast my context reference
        MyContextRef contextRef = (MyContextRef) context;
    
        // Get the length for the first and second dimensions
        unsigned int length1D = MyContextGet1DLength(contextRef);
        unsigned int length2D = MyContextGet2DLength(contextRef);
    
        // Get the 2D float array we want to "Cast"
        float** primitive2DArray = MyContextGet2DArray(contextRef);
    
        // Get the float array class
        jclass floatArrayClass = (*env)->FindClass(env, "[F");
    
        // Check if we properly got the float array class
        if (floatArrayClass == NULL)
        {
            // Ooops
            return NULL;
        }
    
        // Create the returnable 2D array
        jobjectArray myReturnable2DArray = (*env)->NewObjectArray(env, (jsize) length1D, floatArrayClass, NULL);
    
        // Go through the firs dimension and add the second dimension arrays
        for (unsigned int i = 0; i < length1D; i++)
        {
            jfloatArray floatArray = (*env)->NewFloatArray(env, length2D);
            (*env)->SetFloatArrayRegion(env, floatArray, (jsize) 0, (jsize) length2D, (jfloat*) primitive2DArray[i]);
            (*env)->SetObjectArrayElement(env, myReturnable2DArray, (jsize) i, floatArray);
            (*env)->DeleteLocalRef(env, floatArray);
        }
    
        // Return a Java consumable 2D float array
        return myReturnable2DArray;
    }
    
    0 讨论(0)
  • 2020-12-16 03:39

    I've made a simple function for conversion:

    jobjectArray getJNIArray(JNIEnv *env, jobject obj, const vector<vector<float> >& arr) {
        jclass floatClass = env->FindClass("[F"); //
        jsize height = arr.size();
    
        // Create the returnable 2D array
        jobjectArray jObjarray = env->NewObjectArray(height, floatClass, NULL);
    
        // Go through the first dimension and add the second dimension arrays
        for (unsigned int i = 0; i < height; i++) {
            jfloatArray floatArray = env->NewFloatArray(arr[i].size());
            env->SetFloatArrayRegion(floatArray, (jsize) 0, (jsize) arr[i].size(), (jfloat*) arr[i].data());
            env->SetObjectArrayElement(jObjarray, (jsize) i, floatArray);
            env->DeleteLocalRef(floatArray);
        }
    
        return jObjarray;
    }
    
    0 讨论(0)
  • 2020-12-16 03:43

    Unfortunately I don't think you can pass C floats up to Java, you'll have to turn the array into a 2D array of jfloats by converting every member into a jFloat.

    Essentially, you'll have to create the multidimensional jFloatArray, then iterate through the native C array, convert every element into its jFloat representation and store it into the same position in the jFloatArray you just created.

    This part of the documentation should explain it in a bit more depth.

    0 讨论(0)
提交回复
热议问题