unofficial Lua FAQ tiene una entrada sobre sandboxing en Lua. Supongo que puede transponer esa lógica con la suficiente facilidad a su código C/C++.
Véase también LuaFiveTo on the lua-users wiki.
Corrección
De hecho, no es tan trivial como parecía. Pero al final el punto es simple: cargue su porción, presione la tabla _ENV, use lua_setupvalue(L,-2,1)
. Lo importante es que la tabla debe estar en la parte superior de la pila.
Como un pequeño ejemplo, por medio de 2 ambientes morosos a _G para la materia de la lectura a través de metatablas:
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int main(void){
lua_State *L = luaL_newstate();
char *file1 = "file1.lua";
char *file2 = "file2.lua";
luaL_openlibs(L);
luaL_loadfile(L,file2); // S: 1
luaL_loadfile(L,file1); // S: 2
lua_newtable(L); // ENV for file 1: S: 321
lua_newtable(L); // ENV for file 2: S: 4321
//lets have each function have its metatable, where missed lookups are
//instead looked up in the global table _G
lua_newtable(L); // metatable S: 54321
lua_getglobal(L,"_G"); // pushes _G, which will be the __index metatable entry S: 654321
lua_setfield(L,-2,"__index"); // metatable on top S: 54321
lua_pushvalue(L,-1); // copy the metatable S: 554321
lua_setmetatable(L,-3); // set the last copy for env2 S: 54321
lua_setmetatable(L,-3); // set the original for env1 S: 4321
// here we end up having 2 tables on the stack for 2 environments
lua_setupvalue(L,1,1); // first upvalue == _ENV so set it. S: 321
lua_setupvalue(L,2,1); // set _ENV for file S: 21
// Remaining on the stack: 2 chunks with env set.
lua_pcall(L,0,LUA_MULTRET,0);
lua_pcall(L,0,LUA_MULTRET,0);
lua_close(L);
return 0;
}
Y para los archivos 2 Lua:
-- file1.lua
function init()
A="foo"
print("Hello from file1")
print(A)
end
init()
-- file2.lua
-- this shows that stuff defined in file1 will not polute the environment for file2
print("init function is",tostring(init))
function init()
A="bar"
print("Hello from file2")
print(A)
end
init()
Esta es una de las razones por las que he pegado con lua 5.1 en mis propios proyectos por ahora. Creo que las funciones v5.2 'load' y' loadfile' te permiten especificar un entorno; probablemente sean el mejor lugar para comenzar a buscar una solución. – Rook
gracias, pero leí sobre carga y carga, sin embargo, no pude encontrar una solución – Steve
'setuservalue' definitivamente no es la función correcta para usar al tratar de manipular el medio ambiente. Sin embargo, los documentos de lua parecen poco claros sobre lo que deberías estar haciendo. 'lua_load' dice que un único upvalue asociado con un fragmento cargado se establece como su entorno, pero no menciona cómo asociar un upvalue con el fragmento de C. Si estaba cargando el fragmento desde dentro de lua, la versión lua de la función 'load' parece que debe configurar el entorno correctamente. – Rook