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ę:
- Wygenerować odpowiedni nagłówek dla języka C.
- Skompilować i załadować bibliotekę natywną.
- Uzyskać dostęp do tablicy z Javy w C (wskaźnik xDouble).
- 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,