1

考虑以下 C++ 代码和相应的 Emscripten 绑定。

class IBar {
    void qux() = 0;
};

struct BarWrapper : public wrapper<IBar> {
    void qux() override {
        return call<>("qux");
    }
}

EMSCRIPTEN_BINDINGS(IBar) {
    class_<IBar>("IBar")
        .smart_ptr<std::shared_ptr<IBar>>("IBar")
        .function("qux", &IBar::qux)
        .allow_subclass<BarWrapper>("BarWrapper");;
}

class Foo {
    std::shared_ptr<IBar> getBar() const;
    void setBar(std::shared_ptr<IBar> bar);
};

EMSCRIPTEN_BINDINGS(Foo) {
    class_<Options>("Foo")
        .constructor<>()
        .property("bar", &Foo::getBar, &Foo::setBar);
}

在 TypeScript 中,我有以下内容:

class Bar {
    qux() {

    }
}

const bar = new Module.Bar.implement(new Bar())

这里的问题是它Foo::setBar需要一个std::shared_ptrModule.Bar.implement返回一个原始指针。这阻止了我传递barFoo::setBar.

有谁知道如何在这里将原始指针转换为共享指针?或者,有人知道一个好的解决方法吗?

4

2 回答 2

2

虽然 OP 在评论中确实提到他们宁愿不走那条路,但为了完整起见:

添加一个重载/替代方法setBar()需要一个原始指针:

class Foo {
    std::shared_ptr<IBar> getBar() const;
    void setBar(std::shared_ptr<IBar> bar);
    void setBarTakingOwnership(IBar* b) { setBar(std::shared_ptr<IBar>(b)); }
};

并在绑定时使用它:

EMSCRIPTEN_BINDINGS(Foo) {
    class_<Options>("Foo")
        .constructor<>()
        .property("bar", &Foo::getBar, &Foo::setBarTakingOwnership);
}

应该做的伎俩。

注意正如评论中提到的,获取原始指针的所有权始终是薄冰领域,因此如果您必须获取原始指针的所有权,最好在方法名称中非常清楚。

于 2021-10-14T19:42:53.903 回答
1

我想出了一个不返回添加接受原始指针的方法的解决方案。

它通过扩展IBar.

EMSCRIPTEN_BINDINGS(IBar) {
    class_<IBar>("IBar")
        .smart_ptr<std::shared_ptr<IBar>>("IBar")
        .function("qux", &IBar::qux)
        .allow_subclass<BarWrapper, std::shared_ptr<BarWrapper>>("BarWrapper", "BarWrapperSharedPtr");;
}
于 2021-10-14T23:01:31.877 回答