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

创建JNI封装返回std::shared_ptr的C++方法时类型转换错误如何解决

错误原因

你无法直接将std::shared_ptr实例对象强制转换为jlong类型:std::shared_ptr是栈上分配的智能指针对象,并非原生内存地址,reinterpret_cast不支持这种类型转换。

正确的做法是将std::shared_ptr实例分配到堆内存,把堆内存的指针地址转为jlong传给Java层保存,销毁时再把地址转回std::shared_ptr指针释放即可。

修复代码

1. 修改JNI实现(xxx_fooFactory.cpp)

调整nCreate方法的逻辑,改为在堆上创建std::shared_ptr实例:

JNIEXPORT jlong JNICALL Java_xxx_fooFactory_nCreate
        (JNIEnv *env, jclass) {

    JAVA_BINDING_TRY{
           auto fooFactory = createFooFactory();
            if (fooFactory == nullptr) {
                throw JavaBindingException(JavaBindingException::kIllegalStateException, "Unable to create foo factory.");
            }
            // 堆上创建shared_ptr实例,存储指针
            auto* nativeObject = new std::shared_ptr<FooInterface>(fooFactory);
            return reinterpret_cast<jlong>(nativeObject);
    }
    JAVA_BINDING_CATCH(env);
    return 0;
}

nDestroy方法逻辑无需修改,已经符合要求。

2. 修复Java类逻辑错误

你原来的destroyNativeObject方法存在递归调用的问题,会导致运行时栈溢出,修改为调用native的nDestroy方法:

@Override
public void destroyNativeObject(long nativeObject) {
    nDestroy(nativeObject);
}
额外注意事项
  • 后续如果需要在其他JNI接口中使用Java层传入的nativeObject,需要先将其转换为std::shared_ptr<FooInterface>*指针,再解引用拿到智能指针实例使用,不要直接强转为FooInterface*裸指针,否则会破坏引用计数规则,导致内存泄漏或者野指针问题
  • 确认父类PlatformInterface的析构逻辑会正确调用destroyNativeObject方法,避免对象销毁时Native层内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:06:06