我的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.html和https://www.lua.org/pil/14.2.html。 特别是,我的变量是函数参数,而不是全局变量,那么如何通过C API将其转换为全局变量,以便任何分配都将被自定义C函数捕获,如果赋值发生在全局用户数据中,将会采取行动?
顺便说一下,我的userdata是一个指向对象的指针,以避免重复大对象。
这个问题的目标是让Lua对用户友好,正如我所说的,剩下的只剩下一个难题:从C中添加函数参数到当前Lua上下文中的全局变量metatable。我相信这是可能的,但只看到了各种各样的组件,这些组件分散在不同的应用程序中,所以我试图将它们拼凑在一起。如果这是不可能的,那么是的,我会做一些类似于在库中声明assign()或者使用像“__self”这样的自定义索引... – Leo
@Leo:“*问题的目标是让Lua用户友好*“,但Lua *已经*”用户友好“。它不是“完全等同于C/C++”。如果你想以某种形式的全局变量传递函数参数,并在函数中检索它们,你可以。但是在Lua中,它们看起来不像函数的参数。它仍然不会改变任何本地变量不能参与的事实。 –