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

Emscripten创建子类包装时报allocating抽象类类型对象错误的问询

问题根因

Emscripten的call函数默认对引用类型参数使用值拷贝语义,会尝试构造临时的IBar对象做参数序列化,而IBar是抽象类无法实例化,因此触发wire.h中的实例化报错。

可行解决方案

方案1:修改Wrapper层传参逻辑(改造成本最低)

不需要修改对外暴露的IFoo::execute方法签名,仅调整FooWrapper内的call调用逻辑,把引用取地址为指针后再传入:

struct FooWrapper : public wrapper<IFoo> {
    EMSCRIPTEN_WRAPPER(FooWrapper);

    void execute(const IBar &bar) override {
        // 传指针避免触发IBar对象实例化逻辑
        return call<void>("execute", &bar);
    }
};

同步调整绑定代码,补充IBar的抽象类声明:

EMSCRIPTEN_BINDINGS(IFoo) {
    // 先注册IBar为抽象类
    class_<IBar>("IBar")
        .pure_virtual();

    class_<IFoo>("IFoo")
        .function("execute", &IFoo::execute, allow_raw_pointers(), pure_virtual())
        .allow_subclass<FooWrapper>("FooWrapper");
}

方案2:全局特化类型转换规则(适合多场景复用)

如果项目内多处绑定函数都用到了IBar引用作为参数,可以直接特化Emscripten的类型ID规则,强制所有IBar引用都走指针转换逻辑,不需要逐个修改调用点:

namespace emscripten::internal {
// 特化IBar的类型标记,强制按指针处理
template<> struct TypeID<IBar> {
    static constexpr TYPEID get() { return TYPEID::POINTER; }
};
// 常量引用继承IBar的类型规则
template<> struct TypeID<const IBar&> : TypeID<IBar> {};
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:06:05