BindingError: Passing raw pointer to smart pointer is illegal

BindingError: Passing raw pointer to smart pointer is illegal

考虑以下 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 returns 使用原始指针。这使我无法将 bar 传递给 Foo::setBar

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

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

向采用原始指针的 setBar() 添加 overload/alternative:

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);
}

应该可以解决问题。

N.B. 如评论中所述,获取原始指针的所有权始终是薄冰领域,因此如果您必须获取原始指针的所有权指针,方法名最好写的很清楚

我找到了一个解决方案,它不会return 添加一个接受原始指针的方法。

它通过扩展 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");;
}