问题
The interface for my game engine is built using a markup language and Lua, similar to HTML and javascript. As such, visual elements will have handlers for UI events such as a mouse move or click, and each time a handler is to be run, the engine will check if it is compiled yet and if not will compile it via luaL_loadstring
. Handers can be shared either by element duplication or assignment (this.onclick = that.onclick
).
How do I set the environment of a chunk of lua code before running it? The idea is to make element- and event-specific data available to the chunk, and also to link to the environment of the parent UI element. Lua 5.2 changes removed lua_setfenv
, so I am not sure how to accomplish this. The function lua_load allows specifying an environment, but seems to only be used for loading code and not running it.
回答1:
From the reference manual:
You can use load (or loadfile) to load a chunk with a different environment. (In C, you have to load the chunk and then change the value of its first upvalue.)
Setting upvalues is done with lua_setupvalue. So, load your code first, then push the new environment and call lua_setupvalue
the same way you would have called lua_setfenv
before:
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 */
Also, from the end of your question:
The function
lua_load
allows specifying an environment, but seems to only be used for loading code and not running it.
This is not actually the case; load
(the Lua function) lets you specify an environment, but lua_load
(the C function) does not.
Also, while it is "only used for loading code, and not running it", this is the same as luaL_loadstring
- indeed, luaL_loadstring
is just a wrapper around it. lua_load
is a lower-level API function that can be used to implement custom loaders (for example, loading code over the network, or from a compressed file). So if you're already comfortable loading code with luaL_loadstring
before running it with lua_pcall
, lua_load
should look familiar.
来源:https://stackoverflow.com/questions/19167986/how-do-i-set-via-the-lua-c-api-the-environment-table-for-a-chunk-of-lua-code-p