2012-05-30 4 views
18

muszę przejść z JavaPass wrócić i konwertować do listy wektorów list nad JNI

List< List<MyPoint> > points; 

nad JNI do C++ i konwersji do

std::vector< std::vector<MyPoint> > 

Proces ten wektory i powrócić

List< List<MyPoint> > 
  1. Jak poprawnie przejść listę zwrotów i list?
  2. Jak konwertować listę list obiektów w wektorze wektorów obiektów i do tyłu?
+3

Czy próbowałeś [Swig] (http://www.swig.org/), szczególnie [Swig with STL] (http://www.swig.org/Doc2.0/Library.html# Library_stl_cpp_library)? Wygeneruje dla ciebie niezbędny kod kleju JNI. –

+0

Nie, użycie Swig w tym problemie jest niedopuszczalne - tylko standardowe narzędzia. – George

+0

@WdF: Dlaczego jest niedopuszczalne? Możesz przynajmniej wypróbować Swig i zobaczyć, jaki rodzaj kodu Java/JNI generuje. Wszystko, co Swig robi automatycznie, może być również wykonane za pomocą ręcznie pisanego kodu. –

Odpowiedz

14

I rozwiązać ten problem za pomocą standardowych narzędzi.

  1. Tworzenie klasy Java jako obiektów (O) pojemnika (C)
  2. Przełęcz szereg obiektów (O) z kodu Java z natywnym części
  3. utworzyć z matrycy wektora C++ kodu
  4. obliczyć nową wektory
  5. budowy szereg pojemników (C) i wstawić do obiektów (o) tablica
  6. Powrót pojemników (C),

Kod wdrożenia:

W ramach Java:

1 - Tworzenie tablicy z listą punktów

W C++ część:

2 - zbudować wektor wejściowy

std::vector<CurvePoint> src_line; 

jclass java_points_cls = env->FindClass("myPointClass"); 
jmethodID java_mid = env->GetMethodID(java_points_cls, "<init>", "(II)V");  
jfieldID fidX = env->GetFieldID(java_points_cls, "x", "I"); 
jfieldID fidY = env->GetFieldID(java_points_cls, "y", "I"); 

int srcCount = env->GetArrayLength(srcLines); 

for (int i=0; i < srcCount; i++) 
{ 
    jobject cur_pnt = env->GetObjectArrayElement(srcLines, i); 

    LinePoint src_point;   

    src_point.x = env->GetIntField(cur_pnt, fidX); 
    src_point.y = env->GetIntField(cur_pnt, fidY);  

    src_line.push_back(src_point); 
} 

3 - kalkulacja lines

4 - zbudować macierz wyjściowa część

jclass java_line_cls = env->FindClass("myLinesClass"); 

jmethodID java_line_add = env->GetMethodID(java_line_cls, "addPoint", "(II)V"); 
jmethodID java_line_init = env->GetMethodID(java_line_cls, "<init>", "()V"); 

jobjectArray resLines = (jobjectArray) env->NewObjectArray(lines.size(),  java_line_cls, 0); 

for(int i = 0; i < lines.size(); ++i) 
{ 
    jobject cur_line = env->NewObject(java_line_cls, java_line_init); 
    for(int j = 0; j < lines[i].size(); ++j) 
     env->CallVoidMethod(cur_line, java_line_add, 
           lines[i][j].x, 
           lines[i][j].y); 
    env->SetObjectArrayElement(resLines, i, cur_line); 
} 

return resLines; 

Java

5 - Tworzenie listy linii od zwróconej tablicy

+2

Ok, jak to jest lepsze niż JavaCPP? –

+2

Należy używać wyłącznie standardowych narzędzi. Jest to wymagane w przypadku projektu. W innym przypadku można użyć JavaCpp lub SWIG. Uważam, że JavaCpp jest lepszym wariantem. – George

+0

Ach, rozumiem ... Chociaż używanie wyjścia SWIG lub JavaCPP jako odniesienia może być nadal przydatne, myślę, że :) –

2

Jak rozumiem z referencji JNI, JNI może działać tylko z jednowymiarowymi tablicami typów pierwotnych lub obiektów.

Ponieważ po stronie Java musiała przetłumaczyć listę na tablicę. Następnie w części natywnej tablica przeszła i liczba elementów. Nastąpi pożądany wektor i przetworzony. Zwraca w wyniku dwóch tablic (tablica z punktami wszystkich konturów i tablica z liczbą punktów w każdym konturze) i liczbą konturów. Wynikowa tablica jest gromadzona na liście list po stronie Java.

Problem nie został rozwiązany całkowicie, ponieważ JNI nie może przydzielić pamięci dla istniejącego elementu w części natywnej. Dlatego konieczne jest wyodrębnienie danych w części, przydzielenie pamięci dla nich po stronie Java i wypełnienie natywnego.

Możliwe rozwiązać może być użycie spoiw takich jak SWIG lub JavaCpp

+0

+1 dla [JavaCPP] (http://code.google.com/p/javacpp/) :) BTW, możemy zrobić w JNI wszystko, co można zrobić w Javie, to tylko PITA i naprawdę nieefektywna. –

+1

@SamuelAudet dobra praca z JavaCPP - zwykle pracuję z SWIG, ale JavaCPP naprawdę wygląda ładnie. Muszę przyjrzeć się głębiej :) Dzięki! –

1

Można również wykorzystać to project. Pozwoli to na używanie klas java ower JNI jak natywnego.

3
JNIEXPORT jobjectArray JNICALL Java_ProcessInformation_getAllProcessPid (JNIEnv*env,jobject obj) { 

    vector<string>vec; 

    vec.push_back("Ranjan.B.M"); 

    vec.push_back("Mithun.V"); 

    vec.push_back("Preetham.S.N"); 

    vec.push_back("Karthik.S.G"); 

    cout<<vec[0]; 

    cout<<vec[0]; 

    jclass clazz = (env)->FindClass("java/lang/String"); 

    jobjectArray objarray = (env)->NewObjectArray(vec.size() ,clazz ,0); 

    for(int i = 0; i < vec.size(); i++) { 

     string s = vec[i]; 

     cout<<vec[i]<<endl; 

     jstring js = (env)->NewStringUTF(s.c_str()); 

     (env)->SetObjectArrayElement(objarray , i , js); 

    } 

    return objarray;  

}