JNI中如何让GetDirectBufferAddress返回与GetFloatArrayElements同类指针?
问题解决:Direct ByteBuffer在JNI中无法正确传递指针
核心错误分析
你当前JNI代码中的指针赋值逻辑完全错误,导致MBufGet实际写入的是无效内存,自然无法更新Direct ByteBuffer的内容:
jfloat *ptr = NULL; void *temp = (*env)->GetDirectBufferAddress(env, arr); *ptr = *(jfloat *)&temp; // 此处为致命错误
ptr初始化为NULL,直接解引用*ptr会触发未定义行为(大概率写入到内存地址0,与Direct Buffer完全无关)GetDirectBufferAddress返回的就是Direct Buffer底层的原始内存指针,不需要做冗余的强制转换与赋值操作
修正后的JNI代码
直接将GetDirectBufferAddress返回的指针转换为jfloat*即可,和GetFloatArrayElements返回的指针类型完全一致:
JNIEXPORT jint JNICALL Java_com_test_calculate(JNIEnv *env, jobject obj, jobject buf) { // 获取Direct ByteBuffer的底层内存指针 jfloat *ptr = (jfloat*) (*env)->GetDirectBufferAddress(env, buf); if (ptr == NULL) { // 处理获取指针失败的情况,比如传入的不是Direct ByteBuffer return -1; } // 直接调用Matrox的MBufGet,写入到ptr指向的内存 MBufGet(srcBuf, ptr); return 0; }
Java端代码修正注意事项
- 确保传递的是Direct ByteBuffer(你已用
allocateDirect创建,符合要求) - 调用native方法后,需将
ByteBuffer的position重置为0,否则getFloat会从当前position开始读取,导致读到空数据:
// 调用native方法后重置position buffer.position(0); float[] arr = new float[buffer.capacity() / 4]; for(int i = 0; i < arr.length; i++){ arr[i] = buffer.getFloat(); }
或者更高效的方式,直接用关联的FloatBuffer读取:
float[] arr = new float[fb.capacity()]; fb.position(0); fb.get(arr);
原GetFloatArrayElements版本能工作的原因
GetFloatArrayElements返回的是Java float数组的底层内存指针(可能是原数组或拷贝),而修正后的Direct Buffer指针和它本质一致——都是指向可读写的原生内存区域,MBufGet可直接写入。
内容的提问来源于stack exchange,提问作者user3164187
相关产品推荐
相关产品推荐

