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

JNI中如何从C++侧返回ArrayList<Boolean>?

解决JNI中创建并返回ArrayList的SIGSEGV错误

问题根源

触发SIGSEGV的核心原因有两个:

  1. ArrayList的add(Object)方法要求传入引用类型,但直接传递jboolean基本类型时,JVM无法将其当作Object处理,导致内存访问错误。
  2. 调用ArrayList无参构造函数时,错误地多传入了空字符串参数,与<init>()V的方法签名不匹配。

修正后的C++代码

需要将jboolean装箱为Java的Boolean对象后,再传入add方法。以下是完整修正实现:

JNIEXPORT jobject JNICALL Java_createArrayJNI_creatArray
(JNIEnv *env, jobject thisObject) {
    // 1. 获取ArrayList类与无参构造方法
    jclass array_list_cls = env->FindClass("java/util/ArrayList");
    if (array_list_cls == NULL) return NULL;
    
    jmethodID array_list_ctor = env->GetMethodID(array_list_cls, "<init>", "()V");
    if (array_list_ctor == NULL) return NULL;
    
    jobject array_list_obj = env->NewObject(array_list_cls, array_list_ctor);
    if (array_list_obj == NULL) return NULL;
    
    // 2. 获取Boolean类与valueOf静态装箱方法
    jclass boolean_cls = env->FindClass("java/lang/Boolean");
    if (boolean_cls == NULL) return NULL;
    
    jmethodID boolean_valueOf = env->GetStaticMethodID(boolean_cls, "valueOf", "(Z)Ljava/lang/Boolean;");
    if (boolean_valueOf == NULL) return NULL;
    
    // 3. 将jboolean装箱为Boolean对象并添加到ArrayList
    jboolean a = JNI_TRUE;
    jobject boolean_obj = env->CallStaticObjectMethod(boolean_cls, boolean_valueOf, a);
    if (boolean_obj != NULL) {
        jmethodID array_list_add = env->GetMethodID(array_list_cls, "add", "(Ljava/lang/Object;)Z");
        if (array_list_add != NULL) {
            env->CallBooleanMethod(array_list_obj, array_list_add, boolean_obj);
        }
    }
    
    // 释放局部引用,避免内存泄漏
    env->DeleteLocalRef(array_list_cls);
    env->DeleteLocalRef(boolean_cls);
    env->DeleteLocalRef(boolean_obj);
    
    return array_list_obj;
}

关键注意事项

  • 基本类型装箱:JNI中所有需要传入Object的方法,必须使用对应包装类对象。boolean类型通过Boolean.valueOf(boolean)静态方法完成装箱,方法签名为(Z)Ljava/lang/Boolean;。
  • 方法签名匹配:调用JNI方法时必须严格匹配Java方法签名,比如ArrayList无参构造的签名是()V,调用NewObject时不能额外传参。
  • 错误检查:实际开发中要对FindClass、GetMethodID等JNI调用的返回值做NULL检查,提前规避崩溃风险。
  • 局部引用管理:JNI创建的局部引用会占用JVM内存,使用完毕后通过DeleteLocalRef释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Taki HARBI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:01:55