18

ByteBufferバッファとの間で読み取り/書き込みを行うネイティブ関数に(直接) を渡す必要があります。ByteBufferこれらの操作が完了したら、通常の関数を使用して Java コードからアクセスしたいと思います。特に、バッファの現在の状態を反映する必要がありますlimit()position()

JNI はGetDirectBufferAddress()基礎となるバッファーに直接アクセスするために使用するため、読み取り/書き込みが完了した後に // を呼び出す必要があると想定してflip ()いますlimit()position()しかし、私はこれを機能させることができませんでした。たとえば、C からバッファーに数バイトを読み込んで、それに応じて制限と位置を設定した後、Java からそれらのバイトを照会することはできません。バッファーの制限と位置に関する Java の考え方は、私が C コードで行ったことと一致していません。

誰かがこれの実例を教えてもらえますか? 前もって感謝します。

4

1 に答える 1

19

ネイティブ メソッドが書き込まれたバイト数を返すようにすることができます。次に、それに応じて 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 側で検査するときに、バッファーに制限が設定されます。

于 2012-07-04T12:58:50.383 に答える