2011-07-19 5 views
11

W moim kodzie Java mam tablicę 2D float float[x][4] floatArray. Tutaj x może mieć wartość od 1 do 25. Muszę przekazać tę dwuwymiarową tablicę float do metody C++ poprzez JNI. Moja JNI metoda jestNajprostszy sposób przekazywania float [] [] do C++ za pośrednictwem JNI

jboolean MyJNIMethod(JNIEnv * env, jobject obj, jobjectArray myArray) 
{ 
    //how to convert this myArray to something that can be safely passed to C++ method below 
} 

Wewnątrz MyJNIMethod muszę wywołać metodę C++ i przekazać tablicę 2D pływaka pochodzący z Jawy do tej metody

bool MyCplusPlusMethod(float coordinates[][4]) 
    { 

    } 

Mam twardy czas w odpowiednio przekształcając jobject unosić [] [] ze względu na brak rodzimej wiedzy o rozwoju. Czy ktoś może mi powiedzieć najprostszy i najbezpieczniejszy sposób? Dzięki

+2

Można by uprościć to przez przekształcenie (w Javie) tablicy java2d Do Jawna tablica 1-rzędowa 1D i przekazywanie jej do float [] [4]. W C++ tablice 1D i 2D wyglądają tak samo w pamięci. –

+0

Po drugie propozycja przejścia jednowymiarowej tablicy nad JNI. Pamiętaj, że będziesz musiał wtedy przekazać rozmiar. – jackrabbit

+0

Postanowiłem użyć wektora > wewnątrz JNI i C++. Teraz czytam float [] [] w JNI. Zapełnianie wektora > i przekazywanie go do C++ –

Odpowiedz

16

Coś jak to powinno działać:

jboolean MyJNIMethod(JNIEnv * env, jobject obj, jobjectArray myArray) 
{ 
    int len1 = env -> GetArrayLength(myArray); 
    jfloatArray dim= (jfloatArray)env->GetObjectArrayElement(myArray, 0); 
    int len2 = env -> GetArrayLength(dim); 
    float **localArray; 
    // allocate localArray using len1 
    localArray = new float*[len1]; 
    for(int i=0; i<len1; ++i){ 
    jfloatArray oneDim= (jfloatArray)env->GetObjectArrayElement(myArray, i); 
    jfloat *element=env->GetFloatArrayElements(oneDim, 0); 
    //allocate localArray[i] using len2 
    localArray[i] = new float[len2]; 
    for(int j=0; j<len2; ++j) { 
     localArray[i][j]= element[j]; 
    } 
    } 
    //TODO play with localArray, don't forget to release memory ;) 
} 

Należy pamiętać, że jest to zarys. To nie będzie kompilować;) (pisałem go w edytorze Ta overstacks')

W swojej klasie należy zadeklarować sposób natywny:

public native void myJNIMethod(float[][] m); 

w kodzie C, co odpowiada:

JNIEXPORT jboolean JNICALL Java_ClassName_methodName (JNIEnv *, jobject, jobjectArray); 

Oto JNI array operations documentation.

+0

Myślę, że problem polega na tym, jak przekazałbym dynamiczną tablicę 2D float utworzoną w JNI do metody C++, która pobiera float [] []. Nie sądzę, że to możliwe. Czy to jest? Jeśli tak, jaka będzie składnia? –

+0

Tak - jest to możliwe. Spójrz na mój przykład localArray jest wskaźnikiem do dwuwymiarowej, natywnej tablicy. To, jak deklarujesz, zależy od Ciebie. Mój przykład pokazuje, jak wypełnić go danymi przekazywanymi z Javy. – zacheusz

+0

Zaktualizowałem kod przy pomocy float [] [] localArray (nie skompilowałem go). – zacheusz

0

do zwalniania przydzielonej pamięci można zrobić coś takiego:

static void releaseMatrixArray(JNIEnv *env, jobjectArray matrix) { 
int size = (*env)->GetArrayLength(env, matrix); 
for (int i = 0; i < size; i++) { 
    jfloatArray oneDim = (jfloatArray) (*env)->GetObjectArrayElement(env, matrix, i); 
    jfloat *elements = (*env)->GetFloatArrayElements(env, oneDim, 0); 

    (*env)->ReleaseFloatArrayElements(env, oneDim, elements, 0); 
    (*env)->DeleteLocalRef(env, oneDim); 
    } 
} 

uwolnienie lokalnej odniesienia Array:

free(localArray);