Mi objetivo es pasar una matriz de bytes de longitud variable desde el código nativo al lado Java. El método de instancia de la clase Java toma bytearray como su argumento:Pasando matriz de bytes desde el código nativo al lado Java
private void writeBuffer(final byte[] buffer)
{
}
soy capaz de encontrar un método de identificación en el código nativo:
jclass cls = (*env)->FindClass(env,"class_path");
jmethodID writeBufferMethodID = (*env)->GetMethodID(env, cls, "writeBuffer", "([B)V");
pero todavía no puede encontrar la manera de pasar un byte matriz correctamente He tratado:
jbyteArray retArray = (*env)->NewByteArray(env, data_size);
void *temp = (*env)->GetPrimitiveArrayCritical(env, (jarray)retArray, 0);
memcpy(temp, decoded_frame->data[0], data_size);
(*env)->CallVoidMethod(env, obj, writeBufferMethodID, retArray);
(*env)->ReleasePrimitiveArrayCritical(env, retArray, temp, 0);
y también:
retArray = (*env)->NewByteArray(env, data_size);
(*env)->SetByteArrayRegion(env, retArray, 0, data_size, (jbyte *)decoded_frame->data[0]);
(*env)->CallVoidMethod(env, obj, writeBufferMethodID, retArray);
El método Java se llama, pero después de un tiempo la aplicación se bloquea. Además, todos los valores en los buffers de Java que recibo son iguales a cero, por lo que parece que el contenido no se copia en absoluto.
He verificado el contenido de los buffers (decoded_frame-> data [0]) en el lado nativo al escribirlos en el archivo binario y no hay ningún problema, el archivo contiene exactamente lo que esperaba.
Llamo a ese método periódicamente; el tamaño de la matriz puede variar en cada llamada.
¿Cuál es la forma correcta y más efectiva? La asignación de una nueva matriz durante cada llamada es obviamente una idea tonta, pero no sé cómo evitarla si el tamaño de la matriz varía.
EDIT:
he vuelto a escribir mi código de esta manera y parece estar bien ahora.
llamada en un bucle while:
... hacer algo de decodificación ...
if(!retArray)
retArray = (*env)->NewByteArray(env, data_size);
if((*env)->GetArrayLength(env, retArray) != data_size)
{
(*env)->DeleteLocalRef(env, retArray);
retArray = (*env)->NewByteArray(env, data_size);
}
void *temp = (*env)->GetPrimitiveArrayCritical(env, (jarray)retArray, 0);
memcpy(temp, decoded_frame->data[0], data_size);
(*env)->CallVoidMethod(env, obj, writeBufferMethodID, retArray);
(*env)->ReleasePrimitiveArrayCritical(env, retArray, temp, 0);
llamada en la salida del bucle:
(*env)->DeleteLocalRef(env, retArray);
Lo intenté pero nada cambió. Después de un tiempo, noté el error de JVM: 'No se pudo agregar a la tabla de referencia local JNI (tiene 512 entradas)' que me indicó un problema al eliminar las referencias locales de 'retArray'. He reescrito mi código - vea la parte de edición en la pregunta. Ahora pasa la matriz correctamente, pero ocurre otro problema en el lado de Java, no en el alcance de esta pregunta. – vitakot
Todavía es incorrecto llamar a los métodos jni después de GetPrimitiveArrayCritical y antes de ReleasePrimitveArrayCritical. Lea aquí: http://java.sun.com/docs/books/jni/html/functions.html#64717 (busque GetPrimitiveArrayCritical) –
Sí, tiene razón, ¡gracias! Votó para arriba, pero no puede aceptar la respuesta, ya que no fue una fuente de error, en mi caso. – vitakot