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))