Lua为什么报告“找不到指定的过程”。从源代码编译的库?

时间:2019-04-16 12:57:16

标签: lua

我已经为此工作了一段时间,我不知道出了什么问题。

至此,我已经从源代码构建了所有内容,但仍然无法正常工作。我的环境是Windows 10 x64,我正在使用Cygwin的MinGW-w64进行编译。一切都编译为i686(32位)而不是x86_64。

作为参考,我使用gcc的实例实际上是i686-w64-mingw32-gccliblua53.dll.alibyaml.a是使用Lua 5.3.5和LibYAML 0.2.2。从源代码编译的。

我建立了对象:

gcc -DVERSION=\"git-5695363\" -Ilua-5.3/src -Ilibyaml/src/include -c ext/yaml/emitter.c -o emitter.o
gcc -DVERSION=\"git-5695363\" -Ilua-5.3/src -Ilibyaml/src/include -c ext/yaml/scanner.c -o scanner.o
gcc -DVERSION=\"git-5695363\" -Ilua-5.3/src -Ilibyaml/src/include -c ext/yaml/parser.c -o parser.o
gcc -DVERSION=\"git-5695363\" -Ilua-5.3/src -Ilibyaml/src/include -c ext/yaml/yaml.c -o yaml.o

然后链接:

gcc -shared -static -s -Llua-5.3/dist -Llibyaml/dist emitter.o parser.o scanner.o yaml.o -lyaml -llua53.dll -o lyaml.dll

我将其链接为-shared,因为输出是dll,而将其链接为-static,因为我静态链接了libyaml.a。我还尝试通过动态链接到libyaml.dll进行编译,但出现了Lua的相同错误。

我的Lua环境是从源代码和编译器编译的:

> lua53.exe -v
Lua 5.3.5  Copyright (C) 1994-2018 Lua.org, PUC-Rio

运行一个简单的脚本可以正常工作:

> lua53.exe -e 'print("Hello!")'
Hello!

但是我无法加载库:

> lua53.exe -e 'require("lyaml")'
lua53.exe: error loading module 'lyaml' from file 'lyaml.dll':
        The specified procedure could not be found.

stack traceback:
        [C]: in ?
        [C]: in function 'require'
        (command line):1: in main chunk
        [C]: in ?

我知道这是Windows的错误,但我不知道缺少什么过程或它来自哪里。

我还检查了是否满足所有动态链接依赖关系并导出了功能:

enter image description here

如何进一步调试?

2 个答案:

答案 0 :(得分:1)

由于您已经在使用Dependency Walker,因此我建议使用其“配置文件”功能。您可以开始对lua53.exe文件进行性能分析,并在执行require命令时,分析器将向您显示所有正在加载的DLL的跟踪以及与它们相关的所有错误以及错误的详细信息在Lua消息中看不到的内容。

您也可以执行package.loadlib("lyaml.dll", "luaopen_yaml")来确认签名有效;您应该返回一个函数,该函数在执行时将返回实际的包。

答案 1 :(得分:1)

我最终在Linux上构建了所​​有内容,并遇到了同样的问题,但是出现了一个更有用的错误:

$LD_LIBRARY_PATH=. ./test.lua
/bin/lua: error loading module 'lyaml' from file './lyaml.so':
        ./lyaml.so: undefined symbol: luaopen_lyaml
stack traceback:
        [C]: in ?
        [C]: in function 'require'
        ./test.lua:5: in main chunk
        [C]: in ?

问题是Lua将“ luaopen_”符号绑定到正在加载的库的名称。因此,require("somelib")适用于somelib.dll,具有完全匹配的luaopen_somelib导出符号。我可以将库构建为lyaml.dll(以匹配库名),但是此符号已导出为luaopen_yaml,这意味着Lua正在寻找luaopen_lyaml(不存在)。

可能有几种解决方案:

  • 在源代码中修改导出以匹配文件名。
  • 修改文件名以匹配从源代码导出的文件。
  • 完全忽略差异,并使用package.loadlib()允许。

我选择了第三个解决方案。谢谢@PaulKulchenko的第三个解决方案。

由此得出的主要结论是,默认情况下,require(),导出符号和要加载的库文件名之间紧密耦合。