问题
我想从一个 C 程序调用一个 Lua 脚本,它require()
是一个lyaml
模块,用于 LibYAML 的 Lua 绑定。
我从源代码编译了 Lua 5.2,并破解了模块以使其与 Lua 5.2 一起使用。它可以在github上找到。
下面是 Lua 脚本,它适用于 Lua 5.1 和 5.2:
-- foo.lua
require('lyaml')
function hello ()
res = lyaml.load("a: 4\n")
return res.a
end
-- then calling hello() it works like a charm
print( hello() ) -> 4
问题
hello()
我编写了一个应该从脚本调用的 C 程序,遵循《Lua 编程》第 25 章和Lua 5.2 参考手册。
C程序如下:
/* foo.c */
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int main(void)
{
double z;
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "foo.lua"))
luaL_error(L, "error running script: %s", lua_tostring(L, -1));
lua_getglobal(L, "hello");
if (lua_pcall(L, 0, 1, 0) != 0)
luaL_error(L, "error calling hello: %s", lua_tostring(L, -1));
if (!lua_isnumber(L, -1))
luaL_error(L, "result must be number");
z = lua_tonumber(L, -1);
lua_pop(L, 1);
lua_close(L);
return 0;
}
我编译发行:
gcc -Wall -o foo foo.c -ldl -lm -llua
然后在运行时foo
,我在运行时收到以下错误:
PANIC: unprotected error in call tu Lua API (
error running script: error loading module 'lyaml' from file '/path/to/lyaml.so':
/path/to/lyaml.so: undefined symbol: lua_gettop)
Aborted
所以我尝试lyaml
从 C 程序加载,在调用后添加以下行luaL_openlibs()
:
luaL_requiref(L, "lyaml", luaopen_package, 1);
重新编译后错误变为:
PANIC: unprotected error in call tu Lua API (
error running script:
hello.lua:4: attempt to index global 'lyaml' (a nil value))
Aborted
所以我想没有lyaml
符号,require()
调用以某种方式失败。
通过阅读luaL_requiref()
文档,我认为modname
将其调用设置glb
标志设置为 true:
void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
openf
使用字符串modname
作为参数调用函数并将调用结果设置在 中package.loaded[modname]
,就好像该函数已通过 调用一样require
。
如果 glb 为真,也将结果存储到 globalmodname
中。
在堆栈上留下该结果的副本。
我试图require()
在 Lua 脚本中注释调用,结果是一样的。
问题
我做错什么了?我忘记做某事了吗?
编辑
我破解了模块更新已弃用(已删除)的功能/类型及其替代品,如下所示:
lua_strlen() -> luaL_len()
luaL_reg -> luaL_Reg
luaL_getn() -> luaL_len()
然而 Lua 脚本使用lyaml
工作所以我认为问题不是我的 hack。
我尝试lyaml
使用 Lua 5.1 的原始模块。结果是一样的,所以我确定问题不是我的黑客。
更新
添加以下行,正如 Doug Currie 在他的回答中所建议的那样,C 程序与 Lua 5.1 完美配合。不过,我在 5.2 中仍然遇到同样的错误。
lyaml = require('lyaml')