c++lualuabind

luabind can't cast my derived object to base class


I am trying to derive a class in lua(using luabind) that inherits from cpp bound class. But when I try to get a pointer to that class using object cast I get an error.

Base Class:

    class System {

    public:

        virtual ~System() {};
        virtual void Initialize(Document* pDocument) {};
        virtual void Save(Document* pDocument) {};
        virtual void Update(float pDeltaTime) {};
        virtual void Destroy() {};
        virtual const char* GetName() { return "\0"; };;
        virtual System* GetNext();
    };

Here's how I bind the base class:

luabind::class_<Core::Systems::System, 
                                                    luabind::no_bases, 
                                                    std::shared_ptr<Core::Systems::System>,
                                                    Core::Systems::LuaSystem>("System")
.def("Initialize", &:Core::Systems::System::Initialize, &Core::Systems::LuaSystem::DefaultInitialize)
                    .def("Save", &Core::Systems::System::Save, &Core::Systems::LuaSystem::DefaultSave)
                    .def("Destroy", &Core::Systems::System::Destroy, &Core::Systems::LuaSystem::DefaultDestroy)
                    .def("GetName", &Core::Systems::System::GetName,&Core::Systems::LuaSystem::DefaultGetName)
                    .def("Update", &Core::Systems::System::Update, &Core::Systems::LuaSystem::DefaultUpdate)
                    .def("GetNext", &Core::Systems::System::GetNext, &Core::Systems::LuaSystem::DefaultGetNext)

The wrapper class is as follows:

class LuaSystem : public System , public luabind::wrap_base {
            public:

                virtual void Initialize(Document* pDocument) override {
                    call<void>("Initialize", pDocument);
                }
                virtual void Update(float pDeltaTime) override {
                    call<void>("Update", pDeltaTime);
                }
                virtual void Save(Document* pDocument) override {
                    call<void>("Save", pDocument);
                }
                virtual void Destroy() override {
                    call<void>("Destroy");
                }
                virtual const char* GetName() override {
                    return call<const char*>("GetName");
                }
                virtual System* GetNext() override {
                    return call<System*>("GetNext");
                }
                static void DefaultInitialize(System* pPtr, Document* pDocument) {
                    pPtr->System::Initialize(pDocument);
                }
                static void DefaultUpdate(System* pPtr, float pDeltaTime) {
                    pPtr->System::Update(pDeltaTime);
                }
                static void DefaultSave(System* pPtr, Document* pDocument) {
                    pPtr->System::Save(pDocument);
                }
                static void DefaultDestroy(System* pPtr) {
                    pPtr->System::Destroy();
                }
                static const char* DefaultGetName(System* pPtr) {
                    return pPtr->System::GetName();
                }
                static System* DefaultGetNext(System* pPtr) {
                    return pPtr->System::GetNext();
                }
            };

Then in lua i do:

   try {
        luaL_dostring(_env.GetState(),
            "class 'TestSystem' (System)\n"
            "function TestSystem:__init()\n"
            "end\n"
            "function TestSystem:Initialize(pDocument)\n"
            "   print(\"asdasd\")\n"
            "end\n"
            "function TestSystem:Save(pDocument)\n"
            "   print(\"asdasd\")\n"
            "end\n"
            "function TestSystem:Destroy()\n"
            "   print(\"asdasd\")\n"
            "end\n"
            "function TestSystem:GetName()\n"
            "   return \"TestSystem\"\n"
            "end\n"
            "function TestSystem:Update(pDeltaTime)\n"
            "   print(\"asdasd\")\n"
            "end\n");
    }
    catch (std::exception& p) {
        printf(p.what());
    }

    luabind::object _testSystemObj = luabind::globals(_env.GetState())["TestSystem"]();

    Core::Systems::System* _sysObj = luabind::object_cast<Core::Systems::System*(_testSystemObj);

But the line where the cast takes place fails with an error that reads "unable to make cast". I found this: Obtaining a pointer to Lua object instance in C++ Which is exactly what I am doing(and looking for) but for some reason mine is not working.

Any clue? Thanks in advance!


Solution

  • It came down to the fact that I wasn't initializing the base class by calling the __init method on it from within the constructor of the derived class. So doing the following helped.

            luaL_dostring(_env.GetState(),
            "class 'TestSystem' (System)\n"
            "function TestSystem:__init()\n"
            "System:__init()\n"    //Change here!!
            "end\n"
            .
            .