2012-07-04 24 views
13

Muszę przekazać (bezpośrednio) ByteBuffer do natywnych funkcji, które będą odczytywać/zapisywać z/do bufora. Gdy te operacje zostaną zakończone, chciałbym uzyskać dostęp do ByteBuffer z kodu Java przy użyciu zwykłych funkcji; w szczególności, limit() i position() powinny odzwierciedlać bieżący stan bufora.Manipulacja ByteBuffer z JNI

Od JNI użyje GetDirectBufferAddress() bezpośredni dostęp bufor podstawowy, jestem przy założeniu, powinienem zadzwonić flip()/limit()/position() po Skończyłem odczytu/zapisu. Jednak nie byłem w stanie wykonać tej pracy. Na przykład po przeczytaniu kilku bajtów w buforze z C i ustawieniu odpowiednio jego limitu i pozycji, nie mogę zapytać tych bajtów z Javy; Idea Javy dotycząca limitu bufora i pozycji nie jest zgodna z tym, co zrobiłem w kodzie C.

Czy ktoś może wskazać mi na to przykład? Z góry dziękuję.

+0

Powinien działać, to cały pomysł. Jakie pozycje i wartości graniczne ustawiasz i jak oraz jakie wartości dla nich widzisz w Javie? – EJP

Odpowiedz

13

Możesz pozwolić swojej natywnej metodzie zwrócić liczbę zapisanych bajtów. Następnie zaktualizuj ByteBuffer odpowiednio po stronie 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); 
     } 
     ... 
    } 
} 

Edit

Starając się, aby ustawić wartość limitu na stronie C pracuje zbyt więc nie wiem, dlaczego masz problemy z nim.

naiwna implementacja (nic buforowane itd.):

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

Limit jest ustawiony na buforze podczas inspekcji na stronie Java.