在运行之前,如何通过lua C API为一大块lua代码设置环境表?

时间:2013-10-03 19:48:23

标签: c++ c lua lua-api

我的游戏引擎的界面是使用标记语言和Lua构建的,类似于HTML和javascript。因此,可视元素将具有UI事件的处理程序,例如鼠标移动或单击,并且每次运行处理程序时,引擎将检查它是否已编译,如果不是,将通过luaL_loadstring编译它。可以通过元素复制或赋值(this.onclick = that.onclick)来共享Handers。

如何在运行之前设置一大块lua代码的环境?我们的想法是将元素和特定于事件的数据提供给块,并且还链接到父UI元素的环境。 Lua 5.2 changes已移除lua_setfenv,因此我不确定如何完成此操作。函数lua_load允许指定环境,但似乎只用于加载代码而不运行它。

1 个答案:

答案 0 :(得分:7)

来自reference manual

  

您可以使用load(或loadfile)加载具有不同环境的块。 (在C中,您必须加载块,然后更改其第一个upvalue的值。)

使用lua_setupvalue设置值。因此,首先加载您的代码,然后推送新环境,并按照您之前调用lua_setupvalue的方式调用lua_setfenv

luaL_loadfile(L, "file.lua");       /* load and compile handler */
lua_getglobal(L, "my_environment"); /* push environment onto stack */
lua_setupvalue(L, -2, 1);           /* pop environment and assign to upvalue#1 */
/* any other setup needed */
lua_pcall(L, ...);                  /* call handler */

另外,从问题的最后:

  

函数lua_load允许指定环境,但似乎只用于加载代码而不运行它。

事实并非如此; load(Lua函数)允许您指定环境,但lua_load(C函数)不允许。

此外,虽然它“仅用于加载代码,而不是运行它”,但这与luaL_loadstring相同 - 实际上,luaL_loadstring只是它的包装。 lua_load是一个较低级别的API函数,可用于实现自定义加载器(例如,通过网络或压缩文件加载代码)。因此,如果您在使用luaL_loadstring运行代码之前已经习惯使用lua_pcall加载代码,那么lua_load应该看起来很熟悉。