lua - 为什么 Lua 报告“找不到指定的程序”。对于从源代码编译的这个库?
问题描述
我已经为此工作了一段时间,但我不知道出了什么问题。
在这一点上,我已经从源代码构建了所有内容,但它仍然无法正常工作。我的环境是 Windows 10 x64,我正在使用 Cygwin 的 MinGW-w64 进行编译。一切都编译为 i686(32 位)而不是 x86_64。
作为参考,我使用gcc
的实例实际上是i686-w64-mingw32-gcc
. liblua53.dll.a
并libyaml.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。我还尝试使用与 Lua 相同的错误动态链接到 libyaml.dll 进行编译。
我的 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 的错误,但我不知道缺少什么程序或它来自哪里。
我还检查了是否满足所有动态链接依赖项并且正在导出函数:
我该如何进一步调试呢?
解决方案
我最终在 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()
,导出符号和正在加载的库的文件名之间存在紧密耦合。
推荐阅读
- postgresql - 使用 postgresql 作为 .net core 3.0 中的数据库时,代码中的数据迁移首先出错
- go - 在go中将字符串转换为字节
- python - 在 Altair 中保留上一层的工具提示
- c# - 为什么 ConfigurationManager 不包含 OpenExeConfiguration 的定义?C#
- flutter - setState() 未显示在建议的小部件颤动中
- javascript - 来自不同来源的 Cookie
- javascript - Winforms (particles.js) 中的多边形粒子
- typescript - 带有严格空检查的 RegExpMatchArray 的打字稿类型定义
- tfs - TFS API 待处理项目、排除列表、包含列表
- android - 请求位置后从未调用过 onLocationResult