2016-08-16 34 views
3

我的C++程序中有对象,我将其作为userdata传递给Lua,并且我重写此用户数据的metatable,以便对象的索引(通过__newindex和__index)导致对C的调用,C将该赋值转换为影响C++对象或将C++元素转换为Lua值(另一个用户数据或bool,数字,字符串等基本类型)。 userdata作为参数传递给从我的C++程序调用的类似事件的Lua函数。用C API替代Lua中的赋值运算符

luaL_newmetatable(L, "object"); 
lua_pushstring(L, "__index"); 
lua_pushvalue(L, -2); /* pushes the metatable */ 
lua_settable(L, -3); /* metatable.__index = metatable */ 

luaL_openlib(L, NULL, vallib_m, 0); 
luaL_openlib(L, "internal", vallib_f, 0); 

lua_pushstring(L, "__index"); 
lua_pushstring(L, "get"); 
lua_gettable(L, 2); /* get val.get */ 
lua_settable(L, 1); /* metatable.__index = val.get */ 

lua_pushstring(L, "__newindex"); 
lua_pushstring(L, "set"); 
lua_gettable(L, 2); /* get array.set */ 
lua_settable(L, 1); /* metatable.__newindex = val.set */ 

但是,这不允许我分配实际变量本身,只是变量的索引。没有直接覆盖赋值运算符的元事件,所以我正在寻找解决方法。

换句话说,我可以这样做:lua_userdata_object_passed_as_arg_to_event["is_it_true"]=true ,并将其分配lua的boolean变量,以我的内部C++对象,但如果我这样做: lua_userdata_object_passed_as_arg_to_event = new_object() 它将改变Lua的变量引用的,但它不会根据我的理解,对核心对象做任何事情。

我考虑过的一种解决方法是需要开发人员做一些破解lua_userdata_object_passed_as_arg_to_event["__self"] = new_object() 如果他们想更改对象本身,但这是不可取的。

因此,我发现了一些独特的解决方案,通过使用全局变量覆盖赋值运算符并重写全局元表达式运算符,但我期待着看看是否有人能够帮助我阐述此解决方案。见http://lua-users.org/lists/lua-l/2012-01/msg00413.htmlhttps://www.lua.org/pil/14.2.html。 特别是,我的变量是函数参数,而不是全局变量,那么如何通过C API将其转换为全局变量,以便任何分配都将被自定义C函数捕获,如果赋值发生在全局用户数据中,将会采取行动?

顺便说一下,我的userdata是一个指向对象的指针,以避免重复大对象。

回答

3

Lua和C/C++是具有不同需求的不同语言。在C/C++中,变量始终引用特定对象。你可以改变这个对象的内容,但是你永远不能对一个不同的对象进行变量处理。如果您的电子邮件地址为a = b;,则表示您将b的值复制到a。你永远不能改变什么对象a在谈论。

在Lua中,变量不会永久地引用任何东西。因此,变量当前所持有的对象与该对象的值之间存在区别。

通过全局变量函数您的kludge,但local变量是不真实存在的东西。他们在Lua堆栈上的位置;你不能覆盖Lua关于它们的默认行为。

处理这个问题的最好方法是accept C和Lua的区别。用Lua编写代码的方式编写代码。不要试图让Lua代码像C一样工作;这种方式是愚蠢的。他们是不同的语言,你应该拥抱他们的分歧,而不是对他们不利。

如果你想让Lua具有相当于a = b的能力,那么你应该在你的类型中创建一个名为assign的函数,或者可以让你赋值给对象的值。就像要将所有表格元素从一个表格复制到另一个表格一样,您必须编写一个函数来完成此操作。

+0

这个问题的目标是让Lua对用户友好,正如我所说的,剩下的只剩下一个难题:从C中添加函数参数到当前Lua上下文中的全局变量metatable。我相信这是可能的,但只看到了各种各样的组件,这些组件分散在不同的应用程序中,所以我试图将它们拼凑在一起。如果这是不可能的,那么是的,我会做一些类似于在库中声明assign()或者使用像“__self”这样的自定义索引... – Leo

+0

@Leo:“*问题的目标是让Lua用户友好*“,但Lua *已经*”用户友好“。它不是“完全等同于C/C++”。如果你想以某种形式的全局变量传递函数参数,并在函数中检索它们,你可以。但是在Lua中,它们看起来不像函数的参数。它仍然不会改变任何本地变量不能参与的事实。 –