0

我正在编写一个代码,它必须使用 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")

但它们似乎都不起作用。

4

2 回答 2

4

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

然而,这是非常低效的。您必须为该数组中的每个数字创建一个对象。使用Long.valueOf 可以为您提供缓存的对象,但我怀疑该数组中的许多值是否适合有符号字节。

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

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

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


但请注意:您并没有说明您正在使用哪个平台,但例如在 Windows 上,这仍然行不通:Along只是int伪装的,它也是一个 32 位值。jlong另一方面,A总是有 64 位,并且long long 正是因为这个原因才被 typedef 到 a。您盲目地投射指针,因此您的代码将尝试复制两倍于实际拥有的数据。

于 2013-08-02T11:21:11.563 回答
1

[java/lang/Long should be written as [Ljava/lang/Long; and refers to a type, not a class.

The class is Ljava/lang/Long;, which consistent with what NewObjectArray requires—the class for the elements:

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

BTW—Java does support primitive long arrays, which might be faster or simplier if you can change your native method return type.

于 2013-08-02T10:38:49.280 回答