如何使用JNI返回2D长数组

时间:2013-08-02 08:42:42

标签: java-native-interface return-value multidimensional-array

我正在编写一个代码,它必须使用JNI将长数组从C返回到java。但是方法(* env) - > FindClass在我尝试的任何地方都返回NULL。

这是我的代码:

// Returns a 2D long array from C to Java
JNIEXPORT jobjectArray JNICALL Java_awax_tools_AcquisitionWrapper_startAcquisition (JNIEnv *env, jobject obj) {

    // (...) Acquisition code

    // The 2D long array to return
    long** primitive2DArray = data;

    // Get the long array class
    jclass longArrayClass = (*env)->FindClass(env, "[java/lang/Long");

    // Check if we properly got the long array class
    if (longArrayClass == NULL) {
        // Ooops
        return NULL;
    }

    // Create the returnable 2D array
    jobjectArray myReturnable2DArray = (*env)->NewObjectArray(env, (jsize) length1D, longArrayClass, NULL);

    // Go through the firs dimension and add the second dimension arrays
    for (unsigned int i = 0; i < length1D; i++) {
        jlongArray longArray = (*env)->NewLongArray(env, length2D);
        (*env)->SetLongArrayRegion(env, longArray, (jsize) 0, (jsize) length2D, (jlong*) primitive2DArray[i]);
        (*env)->SetObjectArrayElement(env, myReturnable2DArray, (jsize) i, longArray);
        (*env)->DeleteLocalRef(env, longArray);
    }

    // Return a Java consumable 2D long array
    return myReturnable2DArray;
}

我也尝试过:

(*env)->FindClass(env, "[L")
(*env)->FindClass(env, "[Long")
(*env)->FindClass(env, "[java.lang.Long")

但它们似乎都不起作用。

2 个答案:

答案 0 :(得分:3)

如果你真的想要一组java.lang.Long个对象,你必须写[Ljava/lang/Long;。如果你创建了一个数组,那么在Java端就会得到[[Ljava/lang/Long; Long[][]

然而,这非常低效。您必须为该阵列中的每个数字创建一个对象。使用Long.valueOf can give you cached objects,但我怀疑该数组中的许多值是否符合有符号字节。

您应该使用原始Long值,而不是long个对象。除了代码的第一行之外的所有内容都已经这样做了。原始long数组的正确内部名称为[J

jclass longArrayClass = (*env)->FindClass(env, "[J");

您的其余代码是正确的,该方法将返回long[][]


但请注意:您没有说明您正在使用哪个平台,但在Windows上,这仍然不起作用:long只有一个int伪装,它也是32位值。另一方面,jlong总是有64位,并且因为这个原因而被long long类型定义。你是盲目地投射指针,所以你的代码会尝试复制你实际拥有的数据的两倍。

答案 1 :(得分:1)

[java/lang/Long应写为[Ljava/lang/Long;并引用类型,而不是类。

该课程为Ljava/lang/Long;,与NewObjectArray要求的内容一致 - 元素的类:

jobjectArray NewObjectArray(JNIEnv *env, jsize length,
jclass elementClass, jobject initialElement);

BTW-Java确实支持原始long数组,如果您可以更改本机方法返回类型,则可能更快或更简单。