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.