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?
CodePudding user response:
While OP did mention in the comments that they'd rather not go down that road, for the sake of completeness:
Adding an overload/alternative to setBar()
that takes a raw pointer:
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)); }
};
And using it when binding:
EMSCRIPTEN_BINDINGS(Foo) {
class_<Options>("Foo")
.constructor<>()
.property("bar", &Foo::getBar, &Foo::setBarTakingOwnership);
}
Should do the trick.
N.B. As mentioned in the comments, taking ownership of a raw pointer is always thin-ice territory, so if you HAVE to take ownership of a raw pointer, it's better to be very clear in the method name.
CodePudding user response:
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");;
}