如何重新创建setfenvLua 5.2中的功能?我很难理解你应该如何使用新的_ENV环境变量.
在Lua 5.1中,您可以setfenv非常轻松地使用沙箱任何功能.
--# Lua 5.1
print('_G', _G) -- address of _G
local foo = function()
print('env', _G) -- address of sandbox _G
bar = 1
end
-- create a simple sandbox
local env = { print = print }
env._G = env
-- set the environment and call the function
setfenv(foo, env)
foo()
-- we should have global in our environment table but not in _G
print(bar, env.bar)
Run Code Online (Sandbox Code Playgroud)
运行此示例显示输出:
_G table: 0x62d6b0 …Run Code Online (Sandbox Code Playgroud) 请考虑以下示例程序:
#include <stdio.h>
struct base {
int a, b;
};
struct embedded {
struct base base;
int c, d;
};
struct pointed {
struct base* base;
int c, d;
};
static void base_print(struct base* x) {
printf("a: %d, b: %d\n", x->a, x->b);
}
static void tobase_embedded(void* object) {
base_print(object); // no cast needed, suitably converted into first member.
}
static void tobase_pointed(void* object) {
struct base* x = *(struct base**) object; // need this cast?
base_print(x);
}
int main(void) { …Run Code Online (Sandbox Code Playgroud) 我试图通过使用C API将其存储在弱表中来为函数值创建GC终结器.
我开始在纯Lua 5.2中编写原型:
local function myfinalizer()
print 'Called finalizer'
end
function myfunc()
print 'Called myfunc'
end
local sentinels = setmetatable({}, { __mode='k' })
sentinels[myfunc] = setmetatable({}, { __gc=myfinalizer })
myfunc()
myfunc = nil
collectgarbage 'collect'
print 'Closing Lua'
Run Code Online (Sandbox Code Playgroud)
结果输出:
Called myfunc
Called finalizer
Closing Lua
Run Code Online (Sandbox Code Playgroud)
原型似乎按预期工作.以下是C版:
#include <stdlib.h>
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int my_finalizer(lua_State *L)
{
puts("Called finalizer");
return 0;
}
static int my_func(lua_State *L)
{
puts("Called myfunc");
return 0;
}
int main(void)
{ …Run Code Online (Sandbox Code Playgroud) 在Lua 5.3中,C API中的表相关函数接收和返回lua_Integer.
void lua_rawgeti (lua_State *L, int idx, lua_Integer n);
void lua_rawseti (lua_State *L, int idx, lua_Integer n);
lua_Integer luaL_len (lua_State *L, int index);
Run Code Online (Sandbox Code Playgroud)
但是,lua_createtable仍然收到int.
void lua_createtable (lua_State *L, int narr, int nrec);
Run Code Online (Sandbox Code Playgroud)
在下面的示例函数中,源表的长度用于创建大小相同的副本.
static int copy_sequence(lua_State *L) {
lua_Integer len, i;
luaL_checktype(L, 1, LUA_TTABLE);
len = luaL_len(L, 1);
lua_createtable(L, (int)len, 0); /* conversion warning */
for (i = 1; i <= len; i++) {
lua_rawgeti(L, 1, i);
lua_rawseti(L, -2, i);
}
return …Run Code Online (Sandbox Code Playgroud)