I have managed to overcome this issue (creating a smart_ptr to a JS
implementation of an abstract class defined in C++) using the following
pattern:
#include <emscripten/bind.h>
#include <emscripten.h>
class JSObserver : public Observer
{
public:
JSObserver(emscripten::val callbacks) : myCallbacks(callbacks) {}
void onUpdate(const std::string &message)
{
emscripten::val onUpdateCB = myCallbacks["onUpdate"];
onUpdateCB(message);
}
private:
emscripten::val myCallbacks;
};
} // namespace greetings
using namespace emscripten;
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_BINDINGS(my_module)
{
class_<Observer>("Observer")
.smart_ptr<std::shared_ptr<Observer>>("Observer");
class_<JSObserver, base<Observer>>("JSObserver")
.smart_ptr_constructor("JSObserver", &std::make_shared<JSObserver,
emscripten::val>);
}
#endif
See my GitHub for full example:
https://github.com/IvanRomanovski/emscripten-examples/tree/master/observer-pattern
On Sunday, 3 February 2019 15:19:30 UTC+1, [email protected] wrote:
>
> Hi Ricky,
>
> I am having the same problem. Did you ever find a solution?
>
>
> On Monday, May 2, 2016 at 12:30:56 AM UTC+2, Ricky wrote:
>>
>> I've been investigating/playing with Embind and one of the things that
>> currently bothers me is the allow_raw_pointers that I have in locations
>> in my code. Essentially I'm using them in locations where I need the
>> language specific resources to do some work. An example of this could be
>> (but doesn't have to be through the use of Berkley sockets) if I wanted to
>> use JQueries Ajax method to do requests.
>>
>> The code is below if you want to see but basically we have a pure virtual
>> class IAjaxAdapter and App. In it's constructor App takes a
>> std::shared_ptr<IAjaxAdapter> but since IAjaxAdapter is created by running
>> Module.IAjaxAdapter.implement or Module.IAjaxAdapter.extends, it creates a
>> raw pointer, not a smart pointer and you eventually get the error
>> "BindingError: Passing raw pointer to smart pointer is illegal" which makes
>> complete sense.
>>
>> So my question is if its possible to wrap or create a smart pointer when
>> using implement or extends from the javascript side so you do not have to
>> use allow_raw_pointers which would open up the internals of your code to
>> possible abuse if those raw pointers are not handled correctly.
>>
>> Cheers,
>> Ricky
>>
>> ExternalImpl.h
>> #pragma once
>>
>> #include <memory>
>> #include <string>
>> #include <map>
>>
>> class IAjaxAdapter
>> {
>> public:
>> virtual void ajax(std::wstring url, std::map<std::wstring, std::wstring>
>> settings) = 0;
>> };
>>
>> class App
>> {
>> public:
>> App(std::shared_ptr<IAjaxAdapter> ajaxManager);
>> };
>>
>>
>> ExternalImpl.cpp
>> #include "ExternalImpl.h"
>>
>> #ifdef EMSCRIPTEN
>> #include <emscripten/bind.h>
>>
>> using namespace emscripten;
>> #endif
>>
>> App::App(std::shared_ptr<IAjaxAdapter> ajaxManager)
>> {
>> ajaxManager->ajax(L"https://kripken.github.io", {});
>> }
>>
>> #ifdef EMSCRIPTEN
>>
>> struct IAjaxAdapterWrapper : public wrapper<IAjaxAdapter> {
>> EMSCRIPTEN_WRAPPER(IAjaxAdapterWrapper);
>> void ajax(std::wstring url, std::map<std::wstring, std::wstring>
>> settings) {
>> return call<void>("ajax", url, settings);
>> }
>> };
>>
>> EMSCRIPTEN_BINDINGS(ExternalImpl) {
>> class_<IAjaxAdapter>("IAjaxAdapter")
>> .smart_ptr<std::shared_ptr<IAjaxAdapter>>("IAjaxAdapter")
>> .function("ajax", &IAjaxAdapter::ajax, pure_virtual())
>> .allow_subclass<IAjaxAdapterWrapper>("IAjaxAdapterWrapper")
>> ;
>> class_<App>("App")
>> .smart_ptr_constructor("App", &std::make_shared<App, std::shared_ptr<
>> IAjaxAdapter>>)
>> ;
>> }
>> #endif
>>
>>
>> externalImpl.html
>> <HTML>
>> <HEAD>
>> <META NAME="GENERATOR" Content="Microsoft Visual Studio">
>> <TITLE></TITLE>
>> <script src="
>> http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.2.1.min.js" type=
>> "text/javascript"></script>
>> <script src="externalImpl.js" type="text/javascript"></script>
>> <script>
>> $(function () {
>> $("#writeToMe").text("Working");
>> var item = new Module.App(Module.IAjaxAdapter.implement({
>> ajax: function (url, settings) {
>> $("#writeToMe").text('Ajax function called');
>> }
>> }));
>> });
>> </script>
>> </HEAD>
>> <BODY>
>> <div id="writeToMe"></div>
>> </BODY>
>> </HTML>
>>
>>
>>
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.