2012-07-04 8 views
13

Necesito pasar un (directo) ByteBuffer 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() deben reflejar el estado actual del búfer.Manipulación de ByteBuffer de JNI

Desde JNI utilizará GetDirectBufferAddress() para acceder directamente a la memoria intermedia subyacente, estoy asumiendo que debería llamar flip()/limit()/position() después que haya terminado la lectura/escritura. 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 me puede indicar un ejemplo de esto? Gracias por adelantado.

+0

Debería funcionar, esa es toda la idea. ¿Qué posición y valores límites está configurando, y cómo, y qué valores está viendo para ellos en Java? – EJP

Respuesta

13

Puede dejar que su 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

Tratando a cabo para establecer el valor límite en el lado C está trabajando demasiado, así que no sé por qué tienes problemas con él.

aplicación Naive (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 cuando se inspecciona el lado de Java.