Modyfikacja tablicy prymitywów w JNI

0

Witam,
Mam problem z raczej prostą rzeczą. Chcę zmodyfikować tablicę w JNI, tzn. dodać do każdego z elementów 1. Tablicę po modyfikacji chcę dalej przetwarzać w Javie. To musi być zrobione w argumencie metody, nie jako zwracana wartość. Po co to robię? Przenoszę bibliotekę z C.

Klasa wygląda następująco:

public class ArrayModifer {

    static {
        System.load("/jnilibs/libmodify.so");
    }

    public native void modify(double[] x, int n);

}

Plik nagłówka:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class pl_margor_modifyjniarray_ArrayModifer */

#ifndef _Included_pl_margor_modifyjniarray_ArrayModifer
#define _Included_pl_margor_modifyjniarray_ArrayModifer
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     pl_margor_modifyjniarray_ArrayModifer
 * Method:    modify
 * Signature: ([DI)V
 */
JNIEXPORT void JNICALL Java_pl_margor_modifyjniarray_ArrayModifer_modify
  (JNIEnv *, jobject, jdoubleArray, jint);

#ifdef __cplusplus
}
#endif
#endif

Implementacja metody w C:

JNIEXPORT void JNICALL Java_pl_margor_modifyjniarray_ArrayModifer_modify
(JNIEnv *env, jobject obj, jdoubleArray x, jint n) {
    printf("Started JNI lib");
    double* xDouble = (*env)->GetDoubleArrayElements(env, x, 0);
    for (int i = 0; i < n; ++i) {
        printf("before C: %f\n", xDouble[i]);
        xDouble[i] += + 1.0;
        printf("after C: %f\n", xDouble[i]);
    }
}

Main w Javie:

public class Main {

    public static void main(String[] args) {
        ArrayModifer modifer = new ArrayModifer();
        double array[] = {1.0, 2.0, 3.0, 4.0, 5.0};
        modifer.modify(array, array.length);
        System.out.println("Modifed array");
        for(int i = 0; i < array.length; ++i) {
            System.out.println(array[i]);
        }
    }
}

Udało się:

  1. Wygenerować odpowiedni nagłówek dla języka C.
  2. Skompilować i załadować bibliotekę natywną.
  3. Uzyskać dostęp do tablicy z Javy w C (wskaźnik xDouble).
  4. Elementy tablicy są zmodyfikowane w C, jednak zmodyfikowana wartość nie trafia do Javy: w tablicy jest to, co było (wyświetlam dokładnie tą samą tablicę co zainicjowałem).

Dziękuję za poświęcony czas i pozdrawiam,

0

Już sobie poradziłem. Brakowało:

    (*env)->ReleaseDoubleArrayElements(env, x, xDouble, 0);

Po tym tablica w Javie dobrze się aktualizuje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1