2012-07-04 23 views
13

Ich muss eine (direkte) ByteBuffer zu nativen Funktionen übergeben, die aus/in den Puffer lesen/schreiben. Sobald diese Operationen abgeschlossen sind, möchte ich auf den ByteBuffer von Java-Code zugreifen, der die regulären Funktionen verwendet; insbesondere sollten limit() und position() den aktuellen Zustand des Puffers widerspiegeln.Manipulation von ByteBuffer von JNI

Seit JNI GetDirectBufferAddress(), um direkt den zugrunde liegenden Puffer zugreifen wird, geh davon ich mich flip()/limit()/position() nachdem ich fertig bin Lesen/Schreiben rufen soll. Jedoch konnte ich diese Arbeit nicht machen. Zum Beispiel, nachdem ich ein paar Bytes in den Puffer von C gelesen habe, und seine Grenze und Position entsprechend gesetzt habe, kann ich diese Bytes nicht von Java abfragen; Javas Vorstellung von Pufferlimit und Position stimmt nicht mit dem überein, was ich im C-Code gemacht habe.

Kann mich jemand auf ein funktionierendes Beispiel davon hinweisen? Danke im Voraus.

+0

Sollte funktionieren, das ist die ganze Idee. Welche Position und Grenzwerte setzen Sie und wie und welche Werte sehen Sie in Java? – EJP

Antwort

13

Sie könnten Ihre native Methode die Anzahl der geschriebenen Bytes zurückgeben lassen. Aktualisieren Sie dann den ByteBuffer auf der Java-Seite entsprechend.

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); 
     } 
     ... 
    } 
} 

bearbeiten

Der Versuch, aus den Grenzwert auf der C-Seite zu setzen funktioniert auch so weiß ich nicht, warum Sie Probleme damit haben.

Naive Implementierung (nichts im Cache gespeichert usw.):

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; 
} 

Die Grenze für den Puffer gesetzt, wenn auf Java-Seite Inspektion.