una punteros programacion polar orientada objetos matriz matrices español ejemplos dinámica dinamica crear con comando array jni

jni - punteros - matriz polar autocad



¿Cómo acceder a las matrices dentro de un objeto con JNI? (2)

Los tutoriales de JNI, por ejemplo this , cubren bastante bien cómo acceder a campos primitivos dentro de un objeto, así como también cómo acceder a matrices que se proporcionan como argumentos explícitos de funciones (es decir, como subclases de jarray ). Pero, ¿cómo acceder a las matrices Java (primitivas) que son campos dentro de un jobject ? Por ejemplo, me gustaría operar en la matriz de bytes del siguiente objeto Java:

class JavaClass { ... int i; byte[] a; }

El programa principal podría ser algo como esto:

class Test { public static void main(String[] args) { JavaClass jc = new JavaClass(); jc.a = new byte[100]; ... process(jc); } public static native void process(JavaClass jc); }

El lado correspondiente de C ++ sería entonces:

JNIEXPORT void JNICALL Java_Test_process(JNIEnv * env, jclass c, jobject jc) { jclass jcClass = env->GetObjectClass(jc); jfieldID iId = env->GetFieldID(jcClass, "i", "I"); // This way we can get and set the "i" field. Let''s double it: jint i = env->GetIntField(jc, iId); env->SetIntField(jc, iId, i * 2); // The jfieldID of the "a" field (byte array) can be got like this: jfieldID aId = env->GetFieldID(jcClass, "a", "[B"); // But how do we operate on the array??? }

Estaba pensando en usar GetByteArrayElements , pero quiere un ArrayType como argumento. Obviamente me falta algo. ¿Hay una manera de hacer esto?


En gcc 6.3 recibo una advertencia que dice "la desreferenciación del puntero con tipo de letra romperá las reglas de alias estricto" desde una línea como esta:

jdoubleArray arr = *reinterpret_cast<jdoubleArray*>(&mvdata);

Pero como jdoubleArray es en sí mismo un puntero a la clase _jdoubleArray, no es necesario obtener la dirección antes del lanzamiento, y este static_cast funciona sin advertencias:

jdoubleArray arr = static_cast<jdoubleArray>(mvdata);


Espero que eso te ayude un poco ( mira también la referencia de JNI Struct ):

// Get the class jclass mvclass = env->GetObjectClass( *cls ); // Get method ID for method getSomeDoubleArray that returns a double array jmethodID mid = env->GetMethodID( mvclass, "getSomeDoubleArray", "()[D"); // Call the method, returns JObject (because Array is instance of Object) jobject mvdata = env->CallObjectMethod( *base, mid); // Cast it to a jdoublearray jdoubleArray * arr = reinterpret_cast<jdoubleArray*>(&mvdata) // Get the elements (you probably have to fetch the length of the array as well double * data = env->GetDoubleArrayElements(*arr, NULL); // Don''t forget to release it env->ReleaseDoubleArrayElements(*arr, data, 0);

De acuerdo, aquí opero con un método en lugar de un campo (consideré llamar a un limpiador de obtención de Java) pero probablemente también pueda reescribirlo para los campos. No se olvide de lanzar y, como en el comentario, probablemente aún necesite obtener la longitud.

Editar: reescribe tu ejemplo para obtener un campo. Básicamente reemplazar CallObjectMethod por GetObjectField.

JNIEXPORT void JNICALL Java_Test_process(JNIEnv * env, jclass c, jobject jc) { jclass jcClass = env->GetObjectClass(jc); jfieldID iId = env->GetFieldID(jcClass, "i", "I"); // This way we can get and set the "i" field. Let''s double it: jint i = env->GetIntField(jc, iId); env->SetIntField(jc, iId, i * 2); // The jfieldID of the "a" field (byte array) can be got like this: jfieldID aId = env->GetFieldID(jcClass, "a", "[B"); // Get the object field, returns JObject (because Array is instance of Object) jobject mvdata = env->GetObjectField (jc, aID); // Cast it to a jdoublearray jdoubleArray * arr = reinterpret_cast<jdoubleArray*>(&mvdata) // Get the elements (you probably have to fetch the length of the array as well double * data = env->GetDoubleArrayElements(*arr, NULL); // Don''t forget to release it env->ReleaseDoubleArrayElements(*arr, data, 0); }