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 中被贬低了......
但是这个扩展,以及其他 MySQL 扩展,都需要使用模块功能。

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

4

2 回答 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 库而无需重新编译”的东西。

于 2013-05-31T05:35:47.703 回答
1

我用它作为一种快速而肮脏的方法来让我的大部分脚本设置与 5.2 一起工作。我自己没有使用模块,但我的堆栈中有 luasocket、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
于 2013-05-31T09:51:39.650 回答