Доступ к массиву в нативном коде (NDK) из Java (SDK) через JNI - PullRequest
1 голос
/ 03 апреля 2012

Я хочу получить доступ к массиву, который эффективно создается и обновляется в собственном C-коде.При необходимости я мог бы отправить указатель или ссылку из Java-кода на нативную сторону, а C-код заполнил его, чтобы я мог прочитать его со стороны SDK, когда он будет готов к использованию.

В настоящее время,Вот как я это делаю.Но я думаю, что могут быть лучшие способы сделать это, так как я делаю одну копию на стороне C, а затем создаю объект, который создается каждый раз, когда я выполняю чтение на стороне Java.

Моя Javacode:

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

Этот фрагмент кода работает - поэтому я ищу более эффективный или верный способ достижениятоже самое.

Спасибо, что поделились своими мыслями.

1 Ответ

2 голосов
/ 03 апреля 2012

Я думаю 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.

...