【问题标题】:Return a 2D primitive array from C to Java from JNI/NDK从 JNI/NDK 将 2D 原始数组从 C 返回到 Java
【发布时间】:2011-09-02 20:13:11
【问题描述】:

我找到了大量关于如何在 JNI 中生成 2D 原始数组并将其返回给 Java 的文档。但是这些信息无法描述如何在 C 中给定上下文来传递已经存在的 2D 浮点数组 (float**)。

为了明确描述我的问题,我将添加一些我想要实现的 C 伪代码:

// Returns a 2D float array from C to Java
jfloatArray ndk_test_getMy2DArray(JNIEnv* env, jobject thiz, jlong context)
{
    // Cast my context reference
    MyContextRef contextRef = (MyContextRef) context;

    // In case we need it below
    unsigned int length = MyContextGet1DLength(contextRef);

    // Get the 2D Array we want to "Cast"
    float** primitive2DArray = MyContextGet2DArray(contextRef);

    // Hokus pokus...
    // We do something to create the returnable data to Java
    //
    // Below is the missing piece that would convert the primitive
    // 2D array into something that can be returned consumed and consumed
    // by Java

    jfloatArray myReturnable2DArray

    return myReturnable2DArray;
}

我假设这不是直截了当的,因为我找不到任何描述这种情况的东西。

感谢您提供任何有用的信息。

【问题讨论】:

    标签: java c multidimensional-array java-native-interface android-ndk


    【解决方案1】:

    感谢 Timo 的帮助和链接。对于后人,我将添加一个完整的代码集,该代码集将通过从现有的 C 2D 原始数组生成 Java 可使用的 2D 原始数组的过程。

    // 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;
    }
    

    【讨论】:

      【解决方案2】:

      不幸的是,我认为您不能将 C 浮点数传递给 Java,您必须通过将每个成员转换为 jFloat 来将数组转换为 jfloat 的二维数组。

      基本上,您必须创建多维 jFloatArray,然后遍历原生 C 数组,将每个元素转换为其 jFloat 表示形式并将其存储到您刚刚创建的 jFloatArray 中的相同位置。

      documentation 的这一部分应该更深入地解释它。

      【讨论】:

      • 是的,我知道这个限制。如果我的问题不清楚,我很抱歉,但我要问的是这个过程。如何将原始 2D 数组转换为 Java 可以使用的东西。
      • @Claudia,我刚刚在 JNI 文档中添加了一个示例链接。
      • 我已经添加了一个完整的代码集来完成这个过程。感谢您的帮助。
      【解决方案3】:

      我做了一个简单的转换函数:

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 2010-12-09
        • 1970-01-01
        • 2019-11-28
        • 2012-01-11
        • 1970-01-01
        • 2018-01-19
        • 1970-01-01
        • 2017-11-30
        • 1970-01-01
        相关资源
        最近更新 更多