2012-07-04 62 views
13

我需要将(直接)ByteBuffer传递给本地函数,这些函数将从/向缓冲区读取/写入。一旦完成这些操作,我想使用常规函数从Java代码访问ByteBuffer;尤其是limit()position()应该反映缓冲区的当前状态。从JNI操作ByteBuffer

由于JNI将使用GetDirectBufferAddress()直接访问底层的缓冲区,我假设我应该叫flip()/limit()/position()我做读取/写入之后。但是,我一直无法做到这一点。例如,在我从C中读入几个字节到缓冲区并相应地设置其限制和位置后,我无法从Java中查询这些字节; Java关于缓冲区限制和位置的想法与我在C代码中所做的不一致。

任何人都可以指出我的一个工作示例吗?提前致谢。

+0

应该工作,这是整个想法。你在Java中看到了什么样的位置和极限值,以及它们如何以及它们的值? – EJP

回答

13

你可以让你的本地方法返回写入的字节数。然后在Java端相应地更新ByteBuffer。

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

编辑

试行设置在C面是工作太限值,所以我不知道为什么你有它的问题。

幼稚的做法(没有缓存等):

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

在Java方面检查时,限制设置的缓冲。