2012-07-04 49 views
13

Tôi cần chuyển (trực tiếp) ByteBuffer đến các hàm gốc sẽ đọc/ghi từ/vào bộ đệm. Khi các hoạt động này được hoàn thành, tôi muốn truy cập vào ByteBuffer từ mã Java bằng cách sử dụng các chức năng thông thường; cụ thể, limit()position() phải phản ánh trạng thái hiện tại của bộ đệm.Thao tác ByteBuffer từ JNI

Kể từ JNI sẽ sử dụng GetDirectBufferAddress() để truy cập trực tiếp bộ đệm cơ bản, tôi giả sử tôi nên gọi flip()/limit()/position() sau khi tôi thực hiện đọc/ghi. Tuy nhiên, tôi đã không thể thực hiện công việc này. Ví dụ, sau khi tôi đọc một vài byte vào bộ đệm từ C, và thiết lập giới hạn và vị trí của nó cho phù hợp, tôi không thể truy vấn những byte đó từ Java; Ý tưởng của Java về giới hạn và vị trí bộ đệm không nhất quán với những gì tôi đã làm trong mã C.

Ai có thể chỉ cho tôi một ví dụ làm việc về điều này không? Cảm ơn trước.

+0

Nên hoạt động, đó là toàn bộ ý tưởng. Bạn đặt giá trị vị trí và giới hạn, cách thức và giá trị nào cho chúng bạn thấy trong Java? – EJP

Trả lời

13

Bạn có thể cho phép phương thức gốc của mình trả lại số byte đã ghi. Sau đó cập nhật ByteBuffer cho phù hợp ở phía 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); 
     } 
     ... 
    } 
} 

Sửa

Cố gắng ra để thiết lập các giá trị giới hạn ở phía bên C đang làm việc quá nên tôi không biết lý do tại sao bạn có vấn đề với nó.

thực hiện Naive (không có gì cache vv):

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

Giới hạn được đặt trên bộ đệm khi kiểm tra bên Java.