Lua中的全局变量type在隐藏内置的type()函数。

我正在编写一个使用lua进行配置的C ++程序。它使用硬编码脚本设置了几个lua函数:

luaL_loadbuffer(pmLuaState,headerscript,strlen(headerscript),“头脚本”);

然后加载配置lua文件(调用前面提到的函数):

luaL_loadfile(pmLuaState,filename)

不幸的是,Lua配置文件使用了一个名为type的全局变量,因此尝试从我的headerscript调用内置type()函数会导致Lua错误:

attempt to call global 'type' (a string value)

由于我的情况限制,我无法编辑有问题的配置文件。我想知道是否有一种方法明确声明我要使用内置的type()函数。

我新手Lua,所以如果有一种更好的方式来加载这些脚本以避免这种全局隐藏问题,我会考虑它(但是我无法编辑配置脚本)。

Lua版本:5.1.4

原文链接 https://stackoverflow.com/questions/4891251

点赞
stackoverflow用户6236
stackoverflow用户6236

你应该将配置文件 沙盒化,以免影响整个程序的全局环境。

使用空表作为环境,通过luaL_load*() 返回的chunk调用 lua_setfenv()

更新:如果配置文件需要全局环境的内容,请使用元表暴露。

在Lua中:

setfenv(chunk, setmetatable({__index = _G}))

(查阅手册了解如何在C中编写它。)

请注意,这种沙盒化的方法对于不受信任的代码来说过于薄弱。例如,配置文件将能够执行诸如 table.concat = myevilfunction 的操作。查看上面链接的维基页面以获取全面的沙盒化方法(尽管在您的情况下这可能过于繁琐)。

2011-02-03 21:01:10
stackoverflow用户298661
stackoverflow用户298661

一旦全局变量被修改,其值将无法恢复 - 也就是说,必须防止脚本在第一次设置_G.type时进行操作,或者事先存储该值。第二种方法相对不太困难。

local type = type -- 问题解决

或者您可以使用环境来解决此问题。这是一个非常常见的脚本运行方式。

local loadedmodules = {}
import = function(filename)
    if (loadedmodules[filename]) then
        return loadedmodules[filename]
    end
    local env = {}
    local func = loadfile(filename);
    local envmeta = {
        __index = _G -- changed thanks to comments
    }
    setmetatable(env, envmeta) -- 允许导入的脚本只读取我们的全局变量
    setfenv(func, env) -- 设置func的_G为env
    func() -- 加载脚本
    return loadedmodules[filename] = env -- 设置结果并返回它
end

这将是C++的自动头文件防止重复包含和宏自动局限于定义文件范围。

一旦从Lua定义此脚本,您可以从C++加载它并相对轻松地调用它。我不建议从C++中执行任何复杂的Lua逻辑,基于栈的API非常麻烦。

2011-02-03 21:23:13