3

对于下面从 jni 为 java 创建一个 int 数组的代码,为什么我们需要创建一个 temp[] 数组,为什么我们不能只填充 result[] 数组并将其返回给 java.lang. 是因为 java 和 jni 应该使用不同的内存空间因此两个不同的指针?如果是这样,这样做的目的是什么?谢谢

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 temp[256];
 for (i = 0; i < size; i++) {
     temp[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, temp);
 return result;
}
4

1 回答 1

3

原因是您不能直接从 jinitArray 修改对象,因为它们是 Java 对象而不是 C 对象。

在您的示例中,您创建了一个 C 数组,并将其移动到 Java 结构中。更改数组内容时必须遵循相同的方法。您需要一个提供 C 数组的访问器。

一个如何使用 JNI 修改数组的示例。

JNIEXPORT jintArray JNICALL Java_SendArray_loadFile(JNIEnv *env, jobject obj, jintArray input) {

    // Convert incoming JNI jinitarray to C's native jint[]
    jint *inputArray = env->GetIntArrayElements(env, input, NULL); // if last param JNI_TRUE, then a copy is returned.

    if(NULL == inputArray) {
       return NULL ;
    }

    const jsize length = env->GetArrayLength(input);

    for (int i = 0; i < length; i++) {
        inputArray[n] = 0; //We can operate on native jinit[] elements.
    }

    // Convert the C's native jinit[] int JNI jinitarray
    env->ReleaseIntArrayElements(env, input, inputArray, 0); // 0 - copy back the content and free the `input` buffer

    return inputArray;
}

原因是在Java数组中是一个类似于类的引用类型。这就是为什么您需要在 JNI 数组和本机数组之间进行转换的原因。

注意:介绍的示例参考 int 类型。JNI 为基本类型(布尔型、短型、字符型、字节型、整数型、长型、浮点型、双精度型)定义了九种类型的数组,另一种用于对象。

参考:

获取<PrimitiveType>ArrayElements 例程

Java 编程教程 Java 原生接口

访问 Java 数组

于 2013-04-02T14:09:37.890 回答