java jni bytebuffer

java - Manipulación de ByteBuffer de JNI



(1)

Necesito pasar un ByteBuffer (directo) a funciones nativas que leerán / escribirán desde / hacia el búfer. Una vez que se completen estas operaciones, me gustaría acceder al código ByteBuffer desde Java usando las funciones regulares; en particular, limit() y position() deberían reflejar el estado actual del buffer.

Como JNI utilizará GetDirectBufferAddress() para acceder directamente al búfer subyacente, supongo que debo llamar a flip () / limit() / position() vez que haya terminado de leer / escribir. Sin embargo, no he podido hacer que esto funcione. Por ejemplo, después de leer un par de bytes en el búfer de C y establecer su límite y posición en consecuencia, no puedo consultar esos bytes desde Java; La idea de Java del límite y la posición del buffer no son consistentes con lo que hice en el código C.

¿Alguien puede señalarme un ejemplo práctico de esto? Gracias por adelantado.


Podrías dejar que tu método nativo devuelva la cantidad de bytes escritos. Luego actualice el ByteBuffer en consecuencia en el lado de Java.

public class SomeClass { /** * @param buffer input/output buffer * @return number of bytes written to buffer */ private native int nativeMethod(ByteBuffer buffer); public void myMethod() { ByteBuffer buffer = ByteBuffer.allocateDirect(100); int written = nativeMethod(buffer); if (written > 0) { buffer.limit(written); } ... } }

Editar

Tratar de establecer el valor límite en el lado C también está funcionando, así que no sé por qué tienes problemas con él.

Implementación ingenua (nada en caché, etc.):

static jint nativeMethod(JNIEnv *env, jobject obj, jobject buffer) { jclass cls = env->GetObjectClass(buffer); jmethodID mid = env->GetMethodID(cls, "limit", "(I)Ljava/nio/Buffer;"); char *buf = (char*)env->GetDirectBufferAddress(buffer); jlong capacity = env->GetDirectBufferCapacity(buffer); int written = 0; // Do something spectacular with the buffer... env->CallObjectMethod(buffer, mid, written); return written; }

El límite se establece en el búfer al inspeccionar en el lado de Java.