Использование функции "модуль" в Lua 5.2?

У меня есть проект VC++, который использует Lua 5.2 для сценариев.
Я пытаюсь реализовать совместимость MySQL в этом проекте.
Я не являюсь владельцем этого проекта, поэтому я бы предпочел изменить как можно меньше исходного кода, если он вообще есть.
Я скачал и разархивировал файлы из этого расширения в тот же базовый каталог, что и исполняемый файл... и в моем Main.lua файл, я добавил строку require('DBI') как указано, чтобы сделать это на этой вики-странице.

Но когда я запускаю приложение и выполняю скрипт, я получаю:

LUA Fail:
C:\Path\To\bin\DBI.lua:3: attempt to call global 'module' (a nil value)

После небольшого чтения я обнаружил, что функция модуля в Lua 5.2 устарела...
Но это расширение, как и другие расширения MySQL, требует использования функции модуля.

Так что же такое обходной путь для этой проблемы?

2 ответа

Решение

Возможно, вам придется скомпилировать ваш экземпляр Lua с помощью LUA_COMPAT_MODULE; согласно исходному коду: "LUA_COMPAT_MODULE контролирует совместимость с предыдущими функциями модуля" модуль "(Lua) и" luaL_register "(С)".

Этого будет недостаточно, поскольку сам модуль написан с учетом API Lua 5.1. Вы можете либо попытаться найти его версию Lua 5.2, либо использовать что-то наподобие TwoFace Питера Коули, которое "позволяет программе Lua 5.2 загружать большинство библиотек 5.1 C без необходимости какой-либо перекомпиляции".

Я использовал это как быстрый и грязный способ заставить большинство моих скриптов работать с 5.2. Я сам не использовал модуль, но в моем стеке есть такие, как luasocket, copas и т. Д. Я сомневаюсь, что это помогает в вашем конкретном случае, но может быть более полезным.

По сути, я реплицировал C-версию модуля в lua, используя библиотеку отладки для установки функциональной среды. Не красиво, но эй.

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
Другие вопросы по тегам