我想在lua 状态下加载一些函数,然后能够从lua 线程调用这些函数。我正在尝试在线程上,以便它们创建的变量仅限于线程而不出现在全局环境中。setfenv
lua_State *L = luaL_newstate();
luaL_openlibs(L);
dostring(L, "function f1() my_var = 100 print('var set') end");/* create func on state */
/* ^-- a wrapper which does loadstring + pcall with error handling */
lua_State *l1 = lua_newthread(L);
lua_pushthread(l1); /* l1: t */
lua_newtable(l1); /* l1: t T1{} */
lua_newtable(l1); /* l1: t T1{} T2{} */
lua_getglobal(l1, "_G"); /* l1: t T1{} T2{} _G */
lua_setfield(l1, -2, "__index"); /* l1: t T1{} T2{} ( T2.__index = _G) */
lua_setmetatable(l1, -2); /* l1: t T1 ( T1{}.mt = T2 ) */
if (!lua_setfenv(l1, -2)) /* l1: t (t.fenv = T1) */
printf("setfenv fail!\n");
lua_pop(l1, 1);
dostring(l1, "print('l1: ', my_var)"); /* --> nil (expected) */
dostring(l1, "f1() print('l1: ', my_var)"); /* --> l1: 100 (ok) */
dostring(L, "print('L: ', my_var)"); /* --> L: 100 (No!) */
我在这里做错什么了吗?(我不想在线程上加载函数,因为它们可能很多,并且在状态上加载一次似乎是正确的方法)
- 编辑 -
解决方案,似乎是:
- 为每个线程创建一个新的环境表(使用
__index = _G
) - 对于在其中运行的每个函数,执行
setfenv(f1, getfenv(0))