c++shared-ptrwebassemblyemscriptenembind

BindingError: Passing raw pointer to smart pointer is illegal


Consider the following C++ code and corresponding Emscripten bindings.

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

In TypeScript, I have the following:

class Bar {
    qux() {

    }
}

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

The issue here is that Foo::setBar takes a std::shared_ptr but Module.Bar.implement returns a raw pointer. That prevents me from passing bar to Foo::setBar.

Is anyone aware of how to convert a raw pointer to a shared pointer here? Alternatively, is anyone aware of a good workaround?


Solution

  • I figured out a solution that doesn't return adding a method that accepts a raw pointer.

    It works by expanding the bindings for 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");;
    }