使用JNI复制字节缓冲区

时间:2010-02-10 13:40:42

标签: android java-native-interface android-ndk

我在Stackoverflow上发现了很多关于将C / JNI端的char数组复制到Java中的byte []之类的教程/问题,但不是相反。

我正在使用一个需要字节数组的本机C库。我只想从java中的byte []获取数据,最好是C中的unsigned char []。

长话短说:在JNI中从jBytearray复制数据的最佳方法是什么?有没有办法检测它的大小?

2 个答案:

答案 0 :(得分:16)

这是我刚从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; }                                                                                           
    }                                                                                                                       

答案 1 :(得分:13)

将Java byte []复制到本机char*的最佳方法是使用GetByteArrayRegion调用。它完全符合您的要求:将全部或部分字节复制到本机缓冲区中。

使用GetByteArrayElements / ReleaseByteArrayElements需要两个调用而不是一个调用,并且根据VM的实现,将字节[]固定在内存中以防止GC移动它,或者导致副本如此GC可以在不中断本机代码的情况下自由移动原件。 (这也意味着JNI_ABORT将“撤消”更改或保持不变,具体取决于缓冲区是固定还是复制。)

(另请参阅JNI Tips文档的“区域呼叫”部分。)

GetArrayLength来电可用于确定byte[]

的大小