18

C/JNI側からJavaのbyte []のようなものにchar配列をコピーすることを扱うStackoverflowに関するチュートリアル/質問がたくさん見つかりましたが、その逆はありません。

バイト配列を必要とするネイティブ C ライブラリを使用しています。Javaのbyte []から、できればCのunsigned char []にデータを取得したいだけです。

簡単に言えば、JNIでjBytearrayからデータをコピーする最良の方法は何ですか? サイズを検出する方法はありますか?

4

2 に答える 2

18

Java byte[] をネイティブにコピーする最良の方法は、呼び出しchar*を使用することです。GetByteArrayRegionまさにあなたが望むことを行います: バイト配列の全部または一部をネイティブ バッファにコピーします。

GetByteArrayElements/を使用ReleaseByteArrayElementsするには、1 回ではなく 2 回の呼び出しが必要であり、VM の実装に応じて、バイト [] をメモリに固定して GC が移動できないようにするか、コピーを作成して GC がネイティブ コードを中断することなくオリジナルを自由に移動できるようにします。(これはJNI_ABORT、バッファが固定されているかコピーされているかに応じて、変更を「元に戻す」かそのままにすることも意味します。)

( JNI ヒントドキュメントの「リージョン コール」セクションも参照してください。)

GetArrayLengthサイズを決定するために呼び出しを使用できますbyte[]

于 2010-03-19T20:49:40.627 に答える
17

AS/400 JNI ライブラリから取り出した実際の例を次に示します。ネイティブ ユーザー キュー ポインタを解決して、キューの存在をテストします。これは、キュー ライブラリと名前を Java バイト配列 (ジョブの CCSID に変換済み) からネイティブ コードにコピーします。そしてそれを使用します。release 関数の呼び出しに注意してください。これらを変更して、ネイティブ配列の内容を Java バイト配列にコピーし、データを別の方法で移動することができます。

JNIEXPORT jboolean JNICALL Java_com_mycompany_jni400_UserQueue_jniResolve(JNIEnv *jep,jobject thsObj,                
jbyteArray queueLibrary,jbyteArray queueName) {                                                                             
    jbyte            *lib,*nam;                                                                                             
    bool             rtn;                                                                                                   

    thsObj=thsObj;                                                                                                          
    lib=(*jep)->GetByteArrayElements(jep,queueLibrary,0);                                                                   
    nam=(*jep)->GetByteArrayElements(jep,queueName,0);                                                                      
    rtn=(usrq_resolve((byte*)lib,(byte*)nam)!=NULL);                                                                        
    (*jep)->ReleaseByteArrayElements(jep,queueLibrary,lib,JNI_ABORT); /* abort to not copy back contents */                 
    (*jep)->ReleaseByteArrayElements(jep,queueName   ,nam,JNI_ABORT); /* abort to not copy back contents */                 
    if(rtn) { return JNI_TRUE;  }                                                                                           
    else    { return JNI_FALSE; }                                                                                           
    }                                                                                                                       
于 2010-03-10T08:09:58.617 に答える