gpt4 book ai didi

c++ - 如何关闭一段 Lua 代码

转载 作者:行者123 更新时间:2023-11-28 01:31:23 25 4
gpt4 key购买 nike

我想知道是否可以只关闭一段加载了 luaL_dostring 的 Lua 代码,以便相应地释放该 block 中的所有变量。

这是我的简单示例:

lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaL_dostring(L, "a = 2"); // Script A
//How close the script A here?
luaL_dostring(L, "print(a)"); // Script B
lua_close(L);

这段代码在我运行时会打印 2 但我想知道是否有可能以某种方式仅关闭(或释放)内存中第一个加载的 block 以便它打印 nil .

最佳答案

粗略地说,您想对脚本 A 进行沙箱处理,即使用与脚本 B 不同的全局环境运行它。这可以通过将全局表备份到注册表中并将其替换为空表(可选地填充空表)来轻松完成在沙盒中放置任何你需要的表格)。脚本 A 完成后,您只需从注册表中检索旧的全局表并再次将其设为当前全局表。

除此之外,我建议将全局变量的使用减少到绝对最低限度。事实上,我在编写 Lua 代码时从不使用任何全局变量。通常我在本地表中记录信息并传递这些信息。这大概是一个更functional Lua 的写作风格。

#include <iostream>
#include <lua.hpp>

int main() {
lua_State *L = luaL_newstate();
luaL_openlibs(L);

// START SANDBOX

// Push the global table into the registry
lua_pushglobaltable(L);
lua_setfield(L, LUA_REGISTRYINDEX, "globals");

// Push a new empty table and make it the global table
lua_newtable(L);
lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);

// Script A
if (luaL_dostring(L, "a = 2") != 0) {
std::cerr << "lua:" << lua_tostring(L, -1) << '\n';
lua_pop(L, 1);
}

// Retrieve the global table from the registry and make it the global table
lua_getfield(L, LUA_REGISTRYINDEX, "globals");
lua_rawseti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);

// Optional: Remove the global table from the registry
lua_pushnil(L);
lua_setfield(L, LUA_REGISTRYINDEX, "globals");

// END SANDBOX

// Script B
if (luaL_dostring(L, "print(a)") != 0) {
std::cerr << "lua:" << lua_tostring(L, -1) << '\n';
lua_pop(L, 1);
}
lua_close(L);
}
$ clang++ -Wall -Wextra -Wpedantic -I /usr/include/lua5.2/ test.cpp -llua5.2
$ ./a.out
nil

关于c++ - 如何关闭一段 Lua 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51396440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com