You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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端代码修正注意事项

  1. 确保传递的是Direct ByteBuffer(你已用allocateDirect创建,符合要求)
  2. 调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:18:13