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.

Reply via email to