web-dev-qa-db-ja.com

Javaのbyte []をJNIを介してCの関数に渡す:jarraybyteの使い方

これは、JNIを使​​用するのが初めてであり、Cでいくつかの行を記述する必要があるのも初めてです。

私がやろうとしていることはとても簡単です。 Cルーチンを使用して、byte []のエンディアンを切り替えようとしているだけです。

Javaでは、次のように行われます。

public void switchEndianness(byte[] array){

        byte byte1;
        byte byte2;

        for(int i = 0; i < array.length ; i+=2){
            byte1 = array[i];
            byte2 = array[i+1];

            array[i] = byte2;
            array[i+1] = byte1;
        }
}

JNIを使​​用してこれを行うには、JNICALLで同じルーチンを実装しようとしましたが、コンパイルされません。これまでに書いたのはこれです:

JNIEXPORT void JNICALL Java_CEndianness_switchEndianness(JNIEnv *env, jobject obj, jbyteArray array, jint offset, jint length){

    char byte1;
    char byte2;

    int i;
    for(i = offset; i  < length ; i+=2){
        byte1 = array[i];
        byte2 = array[i+1];

        array[i] = byte2;
        array[i+1] = byte1;
    }
}

JbyteArrayタイプのデータを使用する方法がわかりません。 charにjbyteを格納することは可能ですか?別の質問は..このルーチンが終了すると... Javaのbyte []は変更されますか??またはC呼び出し内でのみ変更されますか?

助けて???

みんなありがとう!

33
blutech

getByteArrayElementsでjbyte *を取得できます。

jbyte* bufferPtr = (*env)->GetByteArrayElements(env, array, NULL);

そして、配列の長さを知ることは重要です:

jsize lengthOfArray = (*env)->GetArrayLength(env, array);

Jbyte *と長さがあれば、c-arrayですべてのことができます。最後に、それを解放します:

(*env)->ReleaseByteArrayElements(env, array, bufferPtr, 0);
50
qrtt1

qrttはあなたに素晴らしい答えを与えました。

ただし、JNIには非常に包括的で(比較的)理解しやすいドキュメントがあり、将来JNI機能を再び使用する場合は、前から後ろに読む必要があります。あなたはそれをここで見つけることができます: http://docs.Oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

あなたの特定のケースのために、これが配列の扱いに関するセクションです: http://docs.Oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html#wp1265

8
Jason LeBrun