Entiendo que al usar GetDoubleArrayElements, es la JVM quien decide si copiar o no los elementos de Array. En este caso, ¿hay alguna forma de evitar la copia? Si no, ¿hay alguna otra forma de transferir de Java a C sin copiar? Estoy pasando Arrays muy grandes, y me gustaría poder evitar la copia. Gracias ¿Hay alguna forma de pasar una Java Array a C a través de JNI sin hacer una copia?
Respuesta
El JNI guide dice:
En el JDK/JRE 1.1, los programadores pueden utilizar funciones get/ReleaseArrayElements para obtener un puntero a elementos de la matriz primitivos. Si la VM admite la fijación, el puntero a los datos originales se devuelve; de lo contrario, se hace una copia.
Las nuevas funciones introducidas en JDK/JRE 1.3 permiten que el código nativo obtenga un puntero directo a los elementos de la matriz, incluso si la VM no admite la fijación.
Estas "nuevas funciones" son GetPrimitiveArrayCritical
y ReleasePrimitiveArrayCritical
la que desactivar por completo la recolección de basura y tienen por lo tanto para ser utilizado con cuidado. En resumen, es un problema de VM en lugar de un problema de API. No olvide que sin fijar el recolector de basura puede decidir compactar el montón y mover físicamente su matriz, por lo que el puntero directo sería de poca utilidad después de todo.
Como Peter sugirió que podría trabajar con un java.nio.DoubleBuffer
en lugar de utilizar matrices. La función JNI
void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
le permite acceder a ella.
Me pregunto qué es lo preferido, byte [] con 'GetPrimitiveArrayCritical' o ByteBuffer con' GetDirectBufferAddress'? – Trilarion
Eso realmente depende de su caso de uso. Una consideración podría ser usar 'GetPrimitiveArrayCritical' o' GetArrayElements' cuando sus datos son una salida de su código Java y una entrada de su código C. Debería usar 'GetDirectBufferAddress' cuando sus datos fluyan de otra manera. – Tilo
- 1. pasar punteros entre C y Java a través de JNI
- 2. Devolver una clase C++ a Java a través de JNI
- 3. ¿Hay alguna forma de pasar una anotación Java como parámetro?
- 4. Pasando punteros entre C y Java a través de JNI
- 5. Compartir flujos de salida a través de una interfaz JNI
- 6. Cómo pasar matriz (array de tiempo en Java) de Java a C++ utilizando trago
- 7. El paso de un byte [] en Java a una función en C a través de JNI: cómo utilizar jarraybyte
- 8. ¿Hay alguna forma de pasar parámetros a Runnable?
- 9. ¿Hay alguna forma de pasar una variable al llamar a RenderComponentPresentation?
- 10. ¿Hay alguna forma de conectar un dispositivo Android a una impresora externa a través de Bluetooth?
- 11. Transferencia de cadenas de doble byte (WCHAR) de C++ a Java a través de JNI
- 12. ¿Hay alguna forma de hacer ping a una dirección IP específica con C?
- 13. JNI - ¿Cómo hacer una devolución de llamada desde C++ o C a Java?
- 14. ¿Hay alguna manera de pasar jvm args a través de la línea de comando a maven?
- 15. ¿Hay alguna forma de pasar el iPhone?
- 16. Datos binarios de JNI Stream de C++ a Java
- 17. JNI: pasando bytes de C++ a java
- 18. pasar una matriz a una función de Java
- 19. Mejora de pasar a través de una matriz dos veces (bucle anidado en el mismo array)
- 20. Android: forma más eficiente de pasar algunos bytes de solo lectura a C++ nativo
- 21. problema de bytes que pasa [] a través de JNI a C en Android
- 22. ¿Hay alguna manera de pasar una función de inicialización a una presentación de diapositivas de Orbit?
- 23. Cómo enviar eventos/señal de C a Java en JNI
- 24. Pasar datos POST a través de HTTP sin formato
- 25. ¿Hay alguna forma de hacer bitwise-O enumeraciones en Java?
- 26. ¿Hay alguna forma de obligar a los objetos débiles y/o de referencia suave a pasar GC en Java?
- 27. ¿Sugerencias para pasar de C# a Java?
- 28. Pasar una instancia de tipo anónimo a través de WCF
- 29. pasar argumentos a java a través de horm
- 30. ¿Hay alguna alternativa a C?
Puede usar un DoubleBuffer para envolver un búfer de byte directo. Esto actualiza un área de memoria que se puede usar en Java/C directamente. –