lua 5.1 package.loadlib 和要求。 gcc 构建 windows dll

Posted

技术标签:

【中文标题】lua 5.1 package.loadlib 和要求。 gcc 构建 windows dll【英文标题】:lua 5.1 package.loadlib and require. gcc building windows dll 【发布时间】:2021-12-31 01:24:50 【问题描述】:

我目前正在为Noita 开发一个模组,因此我正在使用它

sock.lua lua-enet ENet

我是一名软件开发人员,但 c、gcc 和 lua 对我来说是新的。

我在当前主 github 文件夹内的 windows 10 上使用 msys2(要清楚我使用 mingw32)使用以下命令自行构建 lua-enet:

gcc -O -shared -o enet.dll enet.c -lenet -llua5.1 -lws2_32 -lwinm --verbose

此外,我必须添加必要的文件,例如头文件:

我这样做了好几次,因为我遇到了类似的错误

找不到指定的模块。

enet 不是有效的 Win32 应用程序

但是上面的 gcc 命令在 DevBuild / Debug 模式下运行 Noita 时有效。 我可以使用Decoda 对其进行调试,并看到库已加载。

但是当我通过 Steam 运行 Noita 时出现以下错误:

'mods/noita-mp/init.lua' 处的 Lua (DoFile) 错误:从文件 'mods\noita-mp\files\libs\ 加载模块 'enet1317_lua-enet-master21-10-2015_lua5-1_32bit' 时出错enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll': Das angegebene Modul wurde nicht gefunden。

enet.dll 64 位版本一。 (没用) enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll 32bit 版本,使用上面的 gcc 命令构建。 (仅适用于调试模式)

附加打印:

Mod enabled: noita-mp 0
LUA: file_util.lua | Noitas root absolute path set to C:\Program Files (x86)\Steam\steamapps\common\Noita   
LUA: ;.\?.lua;C:\Program Files (x86)\Steam\steamapps\common\Noita\lua\?.lua;C:\Program Files (x86)\Steam\steamapps\common\Noita\lua\?\init.lua;;C:\Program Files (x86)\Lua\5.1\lua\?.luac;mods\noita-mp\files\libs\?.lua;C:\Program Files (x86)\Steam\steamapps\common\Noita\mods\noita-mp\files\libs\?.lua;    
LUA: .\?.dll;C:\Program Files (x86)\Steam\steamapps\common\Noita\?.dll;C:\Program Files (x86)\Steam\steamapps\common\Noita\loadall.dll;mods\noita-mp\files\libs\?.dll;C:\Program Files (x86)\Steam\steamapps\common\Noita\mods\noita-mp\files\libs\?.dll;   
LUA: Trying to load enet c library by file name with 'enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll' loading.. Does file exists? false    
LUA: nil    
LUA: Trying to load enet c library by relative path with 'mods\noita-mp\files\libs\enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll' loading.. Does file exists? true    
LUA: nil    
LUA: Trying to load enet c library by absolute path with 'C:\Program Files (x86)\Steam\steamapps\common\Noita\mods\noita-mp\files\libs\enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll' loading.. Does file exists? true    
LUA: nil    
LUA: Trying to load enet c library by absolute path with 'C:\Program Files (x86)\Steam\steamapps\common\Noita\mods\noita-mp\files\libs\enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll' loading.. Does file exists? true    
LUA: nil    
LUA: enet c library 'enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll' was loaded by require load.   
Lua (DoFile) error at 'mods/noita-mp/init.lua': error loading module 'enet1317_lua-enet-master21-10-2015_lua5-1_32bit' from file 'mods\noita-mp\files\libs\enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll':
    Das angegebene Modul wurde nicht gefunden.

init.lua

dofile("mods/noita-mp/files/scripts/util/util.lua")

SetNoitaRootAbsolutePath()

-- Need to add module package to package path, because relative paths are not working
package.path = package.path .. ";"
.. string.gsub(GetRelativePathOfRequiredLibs() .. "/?.lua;", "/", "\\")
.. string.gsub(GetAbsolutePathOfRequiredLibs() .. "/?.lua;", "/", "\\")
print(package.path)

package.cpath = package.cpath .. ";"
.. string.gsub(GetRelativePathOfRequiredLibs() .. "/?.dll;", "/", "\\")
.. string.gsub(GetAbsolutePathOfRequiredLibs() .. "/?.dll;", "/", "\\")
print(package.cpath)


ModMagicNumbersFileAdd("mods/noita-mp/files/data/magic_numbers.xml")

local enet = nil
if enet == nil then
    local fileName = "enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll"
    print("Trying to load enet c library by file name with '" .. fileName .. "' loading.. Does file exists? " .. tostring(FileExists(fileName)))
    enet = package.loadlib(fileName, "luaopen_enet")

    if not enet then
        print(tostring(enet))
        local rel_path = GetRelativePathOfRequiredLibs() .. "/" .. fileName
        rel_path = string.gsub(rel_path, "/", "\\")
        print("Trying to load enet c library by relative path with '" .. rel_path .. "' loading.. Does file exists? " .. tostring(FileExists(rel_path)))
        enet = package.loadlib(rel_path, "luaopen_enet")
    end

    if not enet then
        print(tostring(enet))
        local abs_path = GetAbsolutePathOfRequiredLibs() .. "/" .. fileName
        abs_path = string.gsub(abs_path, "/", "\\")
        print("Trying to load enet c library by absolute path with '" .. abs_path .. "' loading.. Does file exists? " .. tostring(FileExists(abs_path)))
        enet = package.loadlib(abs_path, "luaopen_enet")
    end

    if not enet then
        print(tostring(enet))
        local abs_path = [[C:\Program Files (x86)\Steam\steamapps\common\Noita\mods\noita-mp\files\libs\enet1317_lua-enet-master21-10-2015_lua5-1_32bit.dll]]
        print("Trying to load enet c library by absolute path with '" .. abs_path .. "' loading.. Does file exists? " .. tostring(FileExists(abs_path)))
        enet = package.loadlib(abs_path, "luaopen_enet")
    end

    if enet then
        print("enet c library '" .. fileName .. "' was loaded by function load.")
        enet()
    else
        print(tostring(enet))
        print("enet c library '" .. fileName .. "' was loaded by require load.")
        require("enet1317_lua-enet-master21-10-2015_lua5-1_32bit")
    end
end

我已经尝试将 enet*.dll 放到 noitas 根文件夹中的不同位置,例如单独的 ssd,但没有更改任何内容。

这里有人想解决这个问题吗?

【问题讨论】:

【参考方案1】:

原来我必须使用 Noita 提供的 lua51 dll,而与 Noitas luaJit 相关的正确标头使用的是 2.0.4 版。

对于每个对此感到困惑的人,这就是我构建 enet.dll 的方式

# Introduction to build enet + lua-enet with msys2

## MINGW32

1. start MINGW32 by msys2
2. make sure configure is installed:
    - go to your msys2 installation (C:\msys64\)
    - use windump search and search for "configure"
    - found it in msys64\usr\share\libtool

## ENet

3. download (latest) source code: <https://github.com/lsalzman/enet/releases/tag/v1.3.17>
4. go to your ENet source code download zip and extract to enet-1.3.17

## MINGW32 again

5. in MINGW32 go to that extracted folder (cd "D:\______BACKUP\NoitaMP_repo\NoitaMP\dll building\enet-1.3.17")
6. look into README [and Makefile.am if you are interested] (cat README)
7. run "autoreconf -vfi" in MINGW32 inside of enet-1.3.17 folder
8. run "./configure && make && make install" in MINGW32 inside of enet-1.3.17 folder

## lua-enet

9. download latest version which looks like to be master branch, so download the master branch and keep the date in mind: https://github.com/leafo/lua-enet
10. extract that zip to lua-enet-master_21-10-2015
11. take a look here to know how to build the lua lib, but let me explain in a sec: https://github.com/leafo/lua-enet/issues/1#issuecomment-1960709
12. do not use lua51.dll which is provided by lua installation, use Noitas lua51.dll! See Noitas root installation path.
13. rename lua-enet-master_21-10-2015 to lua-enet-master_21-10-2015_ENet1-3-17_Noita-lua51-dll
14. copy those files
    - ..\enet-1.3.17\.libs\libenet.a
    - ..\enet-1.3.17\include\enet\*
    - ..\Noita\lua51.dll and rename it to noitalua51.dll
        into lua-enet-master_21-10-2015_ENet1-3-17_Noita-lua51-dll
15. download luajit 2.0.4 (because mod community verifed that noita dev team used 2.0.4)
16. copy those files (D:\______BACKUP\NoitaMP_repo\NoitaMP\dll building\LuaJIT-2.0.4)
    - ..\src\lua.h
    - ..\src\luaconf.h
    - ..\src\lualib.h
    - ..\src\lauxlib.h
        into lua-enet-master_21-10-2015_ENet1-3-17_Noita-lua51-dll

## MINGW32 building lua-enet.dll

16. go to your lua-enet-master_21-10-2015_ENet1-3-17_Noita-lua51-dll directory inside of MINGW32 (cd "D:\______BACKUP\NoitaMP_repo\NoitaMP\dll building\lua-enet-master_21-10-2015_ENet1-3-17_Noita-lua51-dll")
17. run "gcc -O -shared -o enet.dll enet.c -lenet -lws2_32 -lwinmm -mwindows -m32 -L /D/______BACKUP/NoitaMP_repo/NoitaMP/dll_building/lua-enet-master_21-10-2015_ENet1-3-17_Noita-lua51-dll/lib -lnoitalua51 --verbose"
18. copy enet.dll into your mods folder. i.e. Noita\mods\noita-mp\files\libs\enet.dll

【讨论】:

以上是关于lua 5.1 package.loadlib 和要求。 gcc 构建 windows dll的主要内容,如果未能解决你的问题,请参考以下文章

lua 学习之错误处理

LUA文件夹组织包

文字字符串 [Lua 5.1]

_VERSION 是 Lua 5.1 中唯一剩下的全局变量吗?

无法读取Lua 5.1上的二进制文件的每个字节

LUA require 搜索路径指定方法