如何在Lua中实现覆盖C方法并在C代码中成功调用被覆盖的方法?

2026-04-01 20:062阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计696个文字,预计阅读时间需要3分钟。

如何在Lua中实现覆盖C方法并在C代码中成功调用被覆盖的方法?

我曾误以为在Lua中可以封装一个类方法,这样当我在C中调用该函数时,它将在Lua中重写的内容执行。我的想法如下:

+C类 class Person {public: Person();// virtual void shout(); // 旨在是}

我曾经认为我可以在lua中覆盖一个类方法,这样当我在C中调用该函数时,它将执行在lua中重写的内容.我的意思是,像这样:

C类

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

假设我将该类绑定到lua,以便在lua中,我可以使用该对象:

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

我想要实现的是这样的:

Lua文件

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

C代码

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

在上面的代码中,您可以看到我正在尝试覆盖lua中的Person方法,并期望从c调用overriden方法.但是,当我尝试它时,不执行overriden方法.我想要实现的是覆盖方法在C中执行.你是如何实现这一目标的?

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

我已经想到了实现这个目标的方法,但我不确定这是不是很好.我的想法是导出的类应该有一个字符串,表示lua中用于保存此类实例的全局变量名.像这样:

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

因此,在lua中,对象负责实现shoutScript()并将全局var分配给对象:

如何在Lua中实现覆盖C方法并在C代码中成功调用被覆盖的方法?

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

使用上面的代码,我可以实现我想要的(尽管没有测试过).但是,有没有其他正确的方法来实现我想要的?

我们在 lqt中所做的,Qt与Lua的自动绑定,是对于我们绑定的每个类,它们都有虚拟方法,我们创建一个代理“shell”类,它将自己注册到Lua状态.

所以对于你的(简化)课程:

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

我们生成以下类:

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(); };

我们使用userdata在Lua中表示这些对象.每个都有自己的环境表,我们指向__newindex和__index元方法(__ index函数在环境中查找,然后在类表中查找).使用此功能,用户可以在对象上存储自定义字段.他还可以实现虚函数,如下所示:

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

在我们的lqt_shell_Person :: shout方法中,我们首先获取参数,然后检查userdata的环境表中是否存在函数shout.如果有,我们用参数调用它.如果没有,我们称之为原始功能.在抽象方法的情况下,我们抛出Lua错误.

希望您觉得这个有帮助.

本文共计696个文字,预计阅读时间需要3分钟。

如何在Lua中实现覆盖C方法并在C代码中成功调用被覆盖的方法?

我曾误以为在Lua中可以封装一个类方法,这样当我在C中调用该函数时,它将在Lua中重写的内容执行。我的想法如下:

+C类 class Person {public: Person();// virtual void shout(); // 旨在是}

我曾经认为我可以在lua中覆盖一个类方法,这样当我在C中调用该函数时,它将执行在lua中重写的内容.我的意思是,像这样:

C类

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

假设我将该类绑定到lua,以便在lua中,我可以使用该对象:

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

我想要实现的是这样的:

Lua文件

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

C代码

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

在上面的代码中,您可以看到我正在尝试覆盖lua中的Person方法,并期望从c调用overriden方法.但是,当我尝试它时,不执行overriden方法.我想要实现的是覆盖方法在C中执行.你是如何实现这一目标的?

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

我已经想到了实现这个目标的方法,但我不确定这是不是很好.我的想法是导出的类应该有一个字符串,表示lua中用于保存此类实例的全局变量名.像这样:

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

因此,在lua中,对象负责实现shoutScript()并将全局var分配给对象:

如何在Lua中实现覆盖C方法并在C代码中成功调用被覆盖的方法?

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

使用上面的代码,我可以实现我想要的(尽管没有测试过).但是,有没有其他正确的方法来实现我想要的?

我们在 lqt中所做的,Qt与Lua的自动绑定,是对于我们绑定的每个类,它们都有虚拟方法,我们创建一个代理“shell”类,它将自己注册到Lua状态.

所以对于你的(简化)课程:

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

我们生成以下类:

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(); };

我们使用userdata在Lua中表示这些对象.每个都有自己的环境表,我们指向__newindex和__index元方法(__ index函数在环境中查找,然后在类表中查找).使用此功能,用户可以在对象上存储自定义字段.他还可以实现虚函数,如下所示:

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

在我们的lqt_shell_Person :: shout方法中,我们首先获取参数,然后检查userdata的环境表中是否存在函数shout.如果有,我们用参数调用它.如果没有,我们称之为原始功能.在抽象方法的情况下,我们抛出Lua错误.

希望您觉得这个有帮助.