1

我想有效地访问在本机 C 代码中创建和更新的数组。如果需要,我可以将 Java 代码中的指针或引用发送到本机端,并让 C 代码填充它,以便在准备好使用时从 SDK 端读取它。

目前,这就是我的做法。但我认为可以有更好的方法来做到这一点,因为我在 C 端做一个副本,然后每次我在 Java 端发出读取时都会创建一个对象。

我的Java代码:

double[] valuesFromNative = getValues();
public static native double[] getValues();
static { System.loadLibrary("test-jni"); }

我的本机(C 而不是 C++)代码:

#define LEN 18
double testDoubleArr[LEN];
jdoubleArray Java_com_test_testActivity_getValues(JNIEnv *env, jclass clazz) {
    jboolean isCopy;
    int i;
    jdoubleArray result = (*env)->NewDoubleArray(env, LEN);
    jdouble* destArrayElems = (*env)->GetDoubleArrayElements(env, result, &isCopy);
    for (i = 0; i < LEN; i++) {
       destArrayElems[i] = testDoubleArr[i];
    }
    if(isCopy == JNI_TRUE) {
        //  isCopy should NEVER be JNI_TRUE in this case, right?
        // so, i could as well replace this condition with
        // assert(isCopy == JNI_FALSE)?
    }
return result;
}

此代码片段有效 - 所以,我正在寻找更有效或更正确的方法来实现相同的目标。

感谢您分享您的想法。

4

1 回答 1

2

我想SetDoubleArrayRegion()会更快。更少的代码和更少的 JNI 调用,这是肯定的。

jdoubleArray result = (*env)->NewDoubleArray(env, LEN); 
(*env)->SetDoubleArrayRegion(env, result, 0, LEN, testDoubleArr);

您甚至不必在 C++ 端创建数组。像这样声明方法:

public static native void getValues(double[] a);   

像这样实现:

void Java_com_test_testActivity_getValues(JNIEnv *env, jclass clazz, jdoubleArray a)
{//...

在 Java 端创建数组,将其缓存在实例变量或其他东西中,并将其传递给 JNI 以在需要时填充。确保关于数组大小的假设在 Java 端和 C 端是相同的。

于 2012-04-03T02:42:20.193 回答