I believe you need to register the smart pointer type for
IThreadQueueItemManager -- you're doing it implicitly for the concrete
class through the smart_ptr_constructor() registration, but since the
interface has no constructor that won't work there.

Something like this should do the trick:

 class_<IThreadQueueItemManager>("IThreadQueueItemManager")
*  .smart_ptr<std::shared_ptr<IThreadQueueItemManager>>()*
  .function("getThreadId", &IThreadQueueItemManager::getThreadId,
pure_virtual())
  ;

-- brion


On Tue, Apr 26, 2016 at 12:14 AM, <[email protected]> wrote:

> I'm trying to implement an interface design pattern in my code but I seem
> to be running into a roadblock regarding embind and it's UnboundTypeError.
> The example code is below:
>
> Interface.h
> #pragma once
>
> #include <memory>
>
> class IThreadQueueItemManager
> {
> public:
>  virtual int getThreadId() = 0;
> };
>
> class ThreadQueueItemManager : public IThreadQueueItemManager
> {
> public:
>  ThreadQueueItemManager();
>  virtual int getThreadId() override;
> };
>
> class ThreadQueueItemManagerFactory {
> protected:
>  ThreadQueueItemManagerFactory();
> public:
>  static std::shared_ptr<ThreadQueueItemManager> create();
>  static std::shared_ptr<IThreadQueueItemManager> createInterface();
>  static int getStaticValue();
> };
>
>
> Interface.cpp
> #include "Interface.h"
>
> #ifdef EMSCRIPTEN
> #include <emscripten/bind.h>
>
> using namespace emscripten;
> #endif
>
> ThreadQueueItemManager::ThreadQueueItemManager()
> {
>
> }
>
> int ThreadQueueItemManager::getThreadId()
> {
>  return 42;
> }
>
> ThreadQueueItemManagerFactory::ThreadQueueItemManagerFactory()
> {
>
> }
>
> int ThreadQueueItemManagerFactory::getStaticValue() {
>  return 8;
> }
>
> std::shared_ptr<ThreadQueueItemManager> ThreadQueueItemManagerFactory::
> create()
> {
>  return std::make_shared<ThreadQueueItemManager>();
> }
>
> std::shared_ptr<IThreadQueueItemManager> ThreadQueueItemManagerFactory::
> createInterface()
> {
>  return std::make_shared<ThreadQueueItemManager>();
> }
>
> #ifdef EMSCRIPTEN
>
> EMSCRIPTEN_BINDINGS(ThreadQueueItemManagerFactory) {
>  class_<IThreadQueueItemManager>("IThreadQueueItemManager")
>   .function("getThreadId", &IThreadQueueItemManager::getThreadId,
> pure_virtual())
>   ;
>  class_<ThreadQueueItemManager>("ThreadQueueItemManager")
>   .smart_ptr_constructor("ThreadQueueItemManager", &std::make_shared<
> ThreadQueueItemManager>)
>   .function("getThreadId", &ThreadQueueItemManager::getThreadId)
>   ;
>  class_<ThreadQueueItemManagerFactory>("ThreadQueueItemManagerFactory")
>   .class_function("create", &ThreadQueueItemManagerFactory::create)
>   .class_function("createInterface", &ThreadQueueItemManagerFactory::
> createInterface)
>   .class_function("getStaticValue", &ThreadQueueItemManagerFactory::
> getStaticValue)
>   ;
> }
> #endif
>
>
> Build step
> "C:\Program Files\Emscripten\emscripten\1.35.0\emcc" --bind -o interface.js
> interface.cpp
>
>
> Html that runs it all
> <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="interface.js" type="text/javascript"></script>
>     <script>
>         $(function () {
>             $("#writeToMe").text("static get: " + Module.
> ThreadQueueItemManagerFactory.getStaticValue());
>             var item = Module.ThreadQueueItemManagerFactory.create();
>             $("#writeToMe").text("Concrete: " + item.getThreadId());
>             var item = Module.ThreadQueueItemManagerFactory.
> createInterface();
>             $("#writeToMe").text("Interface: " + item.getThreadId());
>         });
>     </script>
> </HEAD>
> <BODY>
>     <div id="writeToMe"></div>
> </BODY>
> </HTML>
>
> Essentially if you run this code, getStaticValue works as expected,
> Module.ThreadQueueItemManagerFactory.create() works as expected but sadly
> Module.ThreadQueueItemManagerFactory.createInterface() fails with the
> following:
> UnboundTypeError: Cannot call
> ThreadQueueItemManagerFactory.createInterface due to unbound types:
> NSt3__110shared_ptrI23IThreadQueueItemManagerEE
>
> My hope was I could have multiple different implementations of the
> IThreadQueueItemManager but only need to expose the generic interface to
> javascript. Does anyone have any suggestions on how to only expose an
> interface and not an actual class definition?
>
> I'm assuming the quick and dirty solution would be instead of exposing an
> interface, expose a base class with default implementations of each method
> but I figured I would ask and see if I can go with the interface model
> instead.
>
>
>
> --
> 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.
>

-- 
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