Lua问题 - 运行前加载库文件

3
我正在加载一个 Lua 脚本,该脚本将被运行多次,并且另一个 Lua 脚本作为库被加载以供第一个脚本使用。
让我们看一下 HelloWorldAPI.lua:
function HelloWorld()
    return "Hello world"
end

和 SomeScript.lua :

HelloWorld()

我按照以下顺序做事:
L = luaL_newstate();
luaL_openlibs( L );
luaL_loadfile( L, "HelloWorldAPI.lua" );
luaL_loadfile( L, "SomeScript.lua" );
...
lua_pcall( L, 0, 0, 0 )
...
lua_pcall( L, 0, 0, 0 )
...

一些代码已被删除以保持简单。
但是,当调用HelloWorld函数时,我收到一个错误,说我正在尝试调用空值。
为什么?
在执行lib脚本时声明的函数应该是全局的,因此在SomeScript.lua中应该可用,对吧?
谢谢。

为什么这被标记为 C - Shark
2个回答

3

luaL_loadfile(); 加载并编译一个代码块,将其放在栈的顶部,但不会立即执行它(因此,在第一次调用 luaL_loadfile 后,函数 HelloWorld 在全局 lua 状态中尚未定义)。

接下来,您加载了文件 SomeScript.lua,它现在位于栈的顶部。对 lua_pcall 的调用现在执行了该代码块,该代码块尝试调用(尚未)定义的函数 HelloWorld,从而导致您观察到的错误。

有了这个理解,正确的顺序应该是:

luaL_loadfile( L, "HelloWorldAPI.lua" );
lua_pcall( L, 0, 0, 0 );
luaL_loadfile( L, "SomeScript.lua" );
lua_pcall( L, 0, 0, 0 );

然而,如果需要加载并且立即执行一个文件,您应该使用luaL_dofile

luaL_dofile( L, "HelloWorldAPI.lua" );
luaL_dofile( L, "SomeScript.lua" );

谢谢你的帮助!我没有使用dofile,因为我将所有内容封装到一个对象中,该对象一次加载/解析脚本并多次运行。这使我可以避免每次运行时都需要加载脚本。 - Virus721
@Virus721,与其编写自己的解决方案,不妨考虑使用“require”函数,并通过“package.path”和/或“package.loaders”进行配置。 - Colonel Thirty Two

0

luaL_loadfile 将编译后的脚本作为函数留在堆栈上。

因此,SomeScript.lua 的函数位于顶部,HelloWorldAPI.lua 的函数位于其下方。


感谢您的帮助。 - Virus721

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接