unofficial Lua FAQ在Lua有一個關於沙箱的條目。 我的猜測是,您可以輕鬆地將該邏輯轉置爲您的C/C++代碼。請參閱LuaFiveTo on the lua-users wiki。
修正
這的確不是因爲它似乎微不足道。但最終的觀點很簡單:加載你的塊,按下_ENV表,使用lua_setupvalue(L,-2,1)
。重要的是表格應該位於堆棧的頂部。
作爲一個小例子,使用2-環境經由元表默認爲_G用於讀取的東西:
#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;
}
而對於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()
這就是爲什麼我一直堅持用LUA 5.1在我自己的項目,現在的原因之一。我相信v5.2'load'和'loadfile'函數可以讓你指定一個環境;他們可能是開始尋找解決方案的最佳場所。 – Rook
謝謝,但我讀了關於加載和加載文件,但我找不到解決方案 – Steve
'setuservalue'絕對不是嘗試操作環境時使用的正確函數。但是,lua文檔似乎對你應該做的事情不太清楚。 'lua_load'表示一個與被加載的塊相關聯的單值被設置爲它的環境,但沒有提到你如何去關聯一個upvalue和來自C的塊。如果你是從lua加載塊,那麼lua版本的'load'函數看起來應該正確設置環境。 – Rook