Overriding a C ++ method in lua and calling it back in C ++

I somehow thought that I could override the class method in lua so that when I call this function in C ++ it will do what overloaded in lua. I mean for example:

C ++ Class

class Person { public: Person(); // ctr virtual void shout(); // Meant to be overriden }; 

Suppose I have this class attached to lua, so in lua I can use an object:

 --Lua code p = Person:new() p:shout() 

What I'm trying to achieve looks something like this:

Lua file

 --luafile.lua p = Person:new() --instantiate --override shout() p.shout = function(self) print("OVERRIDEN!") end 

C ++ code

 int main() { lua_State* l = lua_open(); luaL_loadlibs(l); bind_person_class(l); luaL_dofile("luafile.lua"); Person* p = (Person*) get_userdata_in_global(l, "p"); // get the created person in lua p->shout(); // expecting "OVERRIDEN" to be printed on screen lua_close(l); return 0; } 

In the above code, you can see that I am trying to override the Person method in lua and expect the overriden method to be called from C ++. However, when I try it, the overriden method fails. What I'm trying to achieve is the overriden method executed in C ++. How do you achieve this?

====================

I thought it could be done, but I'm not sure if this is good. My idea is that the exported class should have a string representing the name of the global variable in lua, which is used to store an instance of this class. Like this:

 class Person { public: Person(); string luaVarName; // lua global variable to hold this class virtual void shout() { luaL_dostring(luaVarName + ":shoutScript()"); // now shout will call shoutScript() in lua } }; 

So, in lua, the object is responsible for implementing shoutScript () and assigns a global var to the object:

 --LUA p = Person:new() p.shoutScript = function(self) print("OVERRIDEN") end p.luaVarName = "p" 

With the codes above, I can achieve what I want (although I have not tested it). But is there any other, correct way to achieve what I want?

+6
c ++ override methods class lua
source share
2 answers

What we did in lqt , the automatic binding of Qt with Lua is that for each class we have associated that has virtual methods, we create a wrapper proxy class that is registered in the Lua state.

So for your (simplified) class:

 class Person { public: virtual void shout(); // Meant to be overriden }; 

Generate the following class:

 class lqt_shell_Person : public Person { lua_State *L; public: lqt_shell_Person(lua_State *L); // registers itself into the Lua state virtual void shout(); }; 

We represent these objects in Lua using userdata. Each of them has its own environment table, to which we point to the __newindex and __index (the __index function scans in the environment, and then in the class table). Using this, the user can store custom fields for objects. It can also implement virtual functions, for example:

 p = Person.new() function p:shout() print("Hello world!") end 

In our lqt_shell_Person::shout method, we first get the arguments and then check to see if there is a shout function in the userdata environment table. If there is, we call it arguments. If they are not, we call the original function. In the case of abstract methods, we throw a Lua error.

I hope you find this helpful.

+3
source share

Lua is “ideologically” different from C ++. Lua is an OO prototype language . C ++ is an OO class language. Lua can change the runtime of the object interface, C ++ cannot change the type of objects after the object has been created.

So, no matter what you do with the lua object interface, the changes are not reflected in the C ++ program, but remain in lua.

+2
source share

All Articles