2010-08-06 13 views
23

Esta es la primera vez que utilizo el JNI y también la primera vez que tengo que escribir unas líneas en CEl paso de un byte [] en Java a una función en C a través de JNI: cómo utilizar jarraybyte

Lo que intento hacer es muy simple. Solo intento cambiar los extremos de un byte [] usando una rutina C.

en Java que se hace de esta manera:

public void switchEndianness(byte[] array){ 

     byte byte1; 
     byte byte2; 

     for(int i = 0; i < array.length ; i+=2){ 
      byte1 = array[i]; 
      byte2 = array[i+1]; 

      array[i] = byte2; 
      array[i+1] = byte1; 
     } 
}

Así que para hacer esto utilizando JNI, he tratado de imlpement la misma rutina en el JNICALL, pero no compila. Lo que he escrito hasta ahora es la siguiente:

JNIEXPORT void JNICALL Java_CEndianness_switchEndianness(JNIEnv *env, jobject obj, jbyteArray array, jint offset, jint length){ 

    char byte1; 
    char byte2; 

    int i; 
    for(i = offset; i < length ; i+=2){ 
     byte1 = array[i]; 
     byte2 = array[i+1]; 

     array[i] = byte2; 
     array[i+1] = byte1; 
    } 
}

no tengo idea de cómo utilizar el tipo jbyteArray de datos. ¿es posible almacenar un jbyte en un char? Otra pregunta es ... cuando esta rutina termine ... ¿se modificará el byte [] en java? ¿O solo se modifica dentro de la llamada C?

¿Alguna ayuda?

¡Gracias a todos!

Respuesta

40

puede obtener jbyte * por GetByteArrayElements:

jbyte* bufferPtr = (*env)->GetByteArrayElements(env, array, NULL); 

y es importante saber la longitud de la matriz:

jsize lengthOfArray = (*env)->GetArrayLength(env, array); 

Tener jbyte * y duración, puede hacer todas las cosas en c-array. Finalmente, liberándolo:

(*env)->ReleaseByteArrayElements(env, array, bufferPtr, 0); 
+10

en cuenta que si es posible, se recomienda usar '(* env) -> ReleaseByteArrayElements (env , array, bufferPtr, JNI_ABORT); '. El último parámetro significa que la JVM no intentará copiar los bytes desde bufferPtr a la matriz de Java. Muy a menudo, sabes que la función C no cambiará la matriz. –

+5

Si usa C++ en lugar de C, la sintaxis es un poco diferente. No necesita desreferenciar env, y no necesita pasarlo como parámetro. Por ejemplo, bufferPtr = env-> GetByteArrayElements (array, NULL). –

8

qrtt le ha dado una gran respuesta.

Sin embargo, el JNI tiene una documentación muy completa y (relativamente) fácil de entender que debe leer de adelante hacia atrás si va a utilizar funciones JNI nuevamente en el futuro. Lo puedes encontrar aquí: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

para su caso particular, aquí está la sección sobre el tratamiento de matrices: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp1265

+0

la url ha cambiado. :) http://docs.oracle.com/javase/1.4.2/docs/guide/jni/spec/jniTOC.html – qrtt1

+1

la URL se ha cambiado de nuevo: http://docs.oracle.com/javase/7/ docs/technotes/guides/jni/spec/jniTOC.html – Chris

+6

Nadie lee la documentación de adelante hacia atrás. –

Cuestiones relacionadas