在Lua 5.2中使用'module'函数?

3
我有一个使用Lua 5.2进行脚本编写的VC++项目。我正在尝试将MySQL兼容性纳入该项目中。由于不是我的项目,因此如果可能的话,我希望尽可能少地更改源代码。我已经从这个扩展下载并解压缩了文件到与可执行文件相同的基目录中...并且在我的Main.lua文件中,我按照这个wiki页面上所述添加了require('DBI')行。但是当我运行应用程序并执行脚本时,我得到以下错误:
LUA Fail:
C:\Path\To\bin\DBI.lua:3: attempt to call global 'module' (a nil value)

经过简单阅读,我发现在Lua 5.2中module函数已被弃用...
但是这个扩展及其他MySQL扩展需要使用module函数。

那么有没有解决这个问题的方法呢?

2个回答

2

你可能需要使用LUA_COMPAT_MODULE编译Lua实例;根据源代码:“LUA_COMPAT_MODULE控制与先前模块函数'module'(Lua)和'luaL_register'(C)的兼容性”。

但这还不够,因为该模块本身是基于Lua 5.1 API编写的。你可以尝试查找其Lua 5.2版本,或使用像Peter Cawley的TwoFace这样的工具,“使Lua 5.2程序能够加载大多数5.1的C库,而无需重新编译”。


添加预编译器标志似乎起了作用,但我仍然遇到了太多问题导致程序崩溃。使用TwoFace没有任何改变,所以最终我决定硬着头皮将MySQL C++连接器的引用和函数直接添加到源代码中。如果有人知道更好的方法,并且已经成功地让LuaDBI(或类似)MySQL扩展与使用Lua 5.2的应用程序一起工作,请告诉我! - RectangleEquals

1
我用这种快速而粗略的方法来让我的脚本工作在5.2版本上。 我自己没有使用模块,但我的堆栈中有luasocket、copas等模块。 我怀疑这不会对你的特定情况有所帮助,但可能在更普遍的情况下有一些用处。
本质上,我使用debug库复制了Lua中模块的C版本,以设置函数环境。虽然不太美观,但也能用。
if not module then
    function module(modname,...)
        local function findtable(tbl,fname)
            for key in string.gmatch(fname,"([%w_]+)") do
                if key and key~="" then
                    local val = rawget(tbl,key)
                    if not val then
                        local field = {}
                        tbl[key]=field
                        tbl = field
                    elseif type(val)~="table" then
                        return nil
                    else
                        tbl = val
                    end
                end
            end
            return tbl
        end

        assert(type(modname)=="string")
        local value,modul = package.loaded[modname]
        if type(value)~="table" then
            modul = findtable(_G,modname)
            assert(modul,"name conflict for module '"..modname.."'" )
            package.loaded[modname] = modul
        else
            modul = value
        end

        local name = modul._NAME
        if not name then
            modul._M = modul
            modul._NAME = modname
            modul._PACKAGE = string.match(modname,"([%w%._]*)%.[%w_]*$")
        end
        local func = debug.getinfo(2,"f").func
        debug.setupvalue(func,1,modul)
        for _,f in ipairs{...} do f(modul) end
    end

    function package.seeall(modul)
        setmetatable(modul,{__index=_G})
    end
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接