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

Using the 'module' function in Lua 5.2?

本文关键字:函数 module Lua      更新时间:2023-10-16

我有一个vc++项目,使用Lua 5.2编写脚本。
我正试图实现MySQL兼容性到这个项目。
我不是这个项目的所有者,所以我希望尽可能少地修改源代码,如果有的话。
我已经下载并解压缩了文件从这个扩展到相同的基本目录作为可执行文件…在我的Main.lua文件中,我已经添加了require('DBI')行,如本wiki页面所述。

但是当我运行应用程序并执行脚本时,我得到:

LUA Fail:
C:PathTobinDBI.lua:3: attempt to call global 'module' (a nil value)

经过一些简单的阅读,我发现模块函数在Lua 5.2中贬值了…
但是这个扩展,以及其他MySQL扩展,需要使用模块函数。

那么这个问题的解决方法是什么呢?

你可能需要用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库,而不需要任何重新编译"。

我使用这作为一种快速而肮脏的方法来让我的大部分脚本设置在5.2中工作。我自己没有使用模块,但在我的堆栈中有luassocket, copas等。我怀疑这对你的具体情况是否有帮助,但可能在更普遍的情况下有一些用处。

基本上,我在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