web-dev-qa-db-ja.com

JNIを使​​用したバイトバッファのコピー

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

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

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

18
Daniel Sloof

これは、AS/400 JNIライブラリから持ち上げて、ネイティブユーザーキューポインタを解決してキューの存在をテストする実際の例です。キューライブラリと名前をJavaバイト配列(すでにジョブのCCSIDに変換されてネイティブコードに変換され、それを使用します。リリース関数呼び出しに注意してください。これらを変更して、ネイティブ配列の内容を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; }                                                                                           
    }                                                                                                                       
16
Lawrence Dol

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

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

JNIヒント ドキュメントの「RegionCalls」セクションも参照してください。)

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

15
fadden