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

如何为接收std::function&&的函数创建Emscripten绑定?

错误原因

Emscripten默认没有提供std::function类型和JS函数的自动转换规则,因此绑定器无法识别std::function<void()>类型,无法完成JS参数到C++参数的转换,就会抛出你遇到的BindingError报错。另外你代码里的allow_subclass方法中FooWraper拼写错误,少了一个p,正确拼写为FooWrapper,这个错误也可能导致绑定失效。

解决方案

方案1:不修改原有C++接口,手动添加转换逻辑

不需要修改原Foo类的定义,只需要调整绑定代码,把JS传入的函数用emscripten::val接收后手动包装为std::function<void()>即可。
首先添加必要头文件:

#include <emscripten/val.h>
#include <emscripten/bind.h>
using namespace emscripten;

然后修改绑定代码:

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

    void bar(std::function<void()> &&func) override {
        call<void>("bar", std::move(func));
    }
};

EMSCRIPTEN_BINDINGS(Foo) {
        class_<Foo>("Foo")
                .smart_ptr<Foo>("Foo")
                // 手动绑定bar方法,适配JS函数输入
                .function("bar", optional_override([](Foo& self, val js_func) {
                    // 将JS函数包装为std::function
                    std::function<void()> cpp_func = [js_func = std::move(js_func)]() mutable {
                        js_func();
                    };
                    self.bar(std::move(cpp_func));
                }))
                // 修正拼写错误
                .allow_subclass<FooWrapper, std::shared_ptr<FooWrapper>>("FooWrapper", "FooWrapperSharedPtr");
}

方案2:修改接口直接使用emscripten::val

如果允许调整原Foo类的接口,可以直接把参数类型替换为emscripten::val,省去类型转换的步骤,性能也更高:

#include <emscripten/val.h>
using namespace emscripten;

class Foo {
    virtual void bar(val func) = 0;
};

// 调用时直接执行即可
void FooWrapper::bar(val func) override {
    // 同步调用JS函数
    func();
    // 如果需要异步调用,直接存下val实例即可,不需要额外处理生命周期
}

绑定的时候不需要额外处理,直接注册类即可,JS侧的调用方式完全不变。

注意事项

如果你的std::function带有参数或者有返回值,只需要在lambda中增加对应的参数转换逻辑即可,比如std::function<int(std::string)>对应的包装逻辑为:

std::function<int(std::string)> cpp_func = [js_func = std::move(js_func)](std::string arg) {
    return js_func(arg).as<int>();
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:24:03