2012-05-30 8 views
18

que necesito para pasar de JavaPass, vuelvo y convertir a la lista de vectores de las listas de más de JNI

List< List<MyPoint> > points; 

sobre JNI para C++ y convertir a

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

procesar esta vectores y volver

List< List<MyPoint> > 
  1. ¿Cómo corrigen y devuelven la lista de listas?
  2. ¿Cómo se convierte la lista de listas de objetos en vectores de vectores de objetos y hacia atrás?
+3

Has probado [Swig] (http://www.swig.org/), especialmente [Swig with STL] (http://www.swig.org/Doc2.0/Library.html# Library_stl_cpp_library)? Generará el código de pegamento JNI necesario para usted. –

+0

No, el uso de Swig en este problema es inaceptable, solo las herramientas estándar. – George

+0

@WDF: ¿Por qué es inaceptable? Lo menos que puedes hacer es probar Swig out y ver qué tipo de código Java/JNI genera. Todo lo que Swig hace automáticamente también se puede hacer usando solo código escrito a mano. –

Respuesta

14

I resuelto este problema con herramientas estándar.

  1. Crear en clase Java como objetos (O) contenedor (C)
  2. Pass matriz de objetos (O) de código Java para parte nativa
  3. crear a partir de matriz de vector en C++ código
  4. Calcular nuevo vectores
  5. array
  6. Build de los contenedores (C) y se insertan en los objetos (O) array
  7. retorno de los contenedores (C)

Código implementar:

Por parte de java:

1 - Crea una matriz de la lista de puntos de

En C++ parte:

2 - construir vector de entrada

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 - cálculo lines

4 - construir matriz de salida

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 parte

5 - Crear una lista de líneas de matriz devuelta

+2

Ok, ¿cómo es eso mejor que JavaCPP? –

+2

Se deben usar solo herramientas estándar. Este es un requisito para el proyecto. En otro caso, se puede usar JavaCpp o SWIG. Encuentro JavaCpp como mejor variante) – George

+0

Ah, ya veo ... Aunque usar la salida de SWIG o JavaCPP como referencia aún podría ser útil, supongo :) –

2

Como lo entiendo por la referencia JNI, JNI solo puede trabajar con matrices unidimensionales de tipos u objetos primitivos.

Porque en el lado de Java, tuve que traducir la lista en una matriz. Luego, en la parte nativa, la matriz pasó y la cantidad de elementos. Va al vector deseado y se procesa. Se devuelve como resultado de dos matrices (matriz con puntos de todos los contornos y la matriz con el número de puntos en cada contorno) y el número de contornos. La matriz resultante se recopila en una lista de listas en el lado de Java.

Mientras que el problema no se resuelve completamente, porque el JNI no puede asignar memoria para un elemento existente en la parte nativa. Por lo tanto, es necesario extraer los datos en parte, asignar memoria para ellos en el lado de Java y completar el original.

Una posible resolución puede ser el uso de aglutinantes tales como SWIG o JavaCpp

+0

+1 para [JavaCPP] (http://code.google.com/p/javacpp/) :) Por cierto, podemos hacer en JNI todo lo que se puede hacer en Java, es solo un PITA y realmente ineficiente. –

+1

@SamuelAudet Buen trabajo con JavaCPP: normalmente trabajo con SWIG, pero JavaCPP realmente se ve bien. Tengo que echar un vistazo más profundo :) ¡Gracias! –

1

También puede utilizar esto project. Permitirá usar clases Java de JNI como una nativa.

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;  

} 
Cuestiones relacionadas