【问题标题】:Lua issue - Loading a library file before runningLua问题 - 在运行之前加载库文件
【发布时间】:2016-06-14 02:32:47
【问题描述】:

我正在加载一个要运行多次的 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 函数时尝试调用 nil 值。

为什么?

我在执行 lib 脚本时声明的函数应该是全局的,因此在 SomeScript.lua 中可用,对吧?

谢谢。

【问题讨论】:

  • 为什么标记为C

标签: c lua


【解决方案1】:

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 与其编写自己的解决方案,不如考虑使用require 函数,并通过package.path 和/或package.loaders 进行配置。
【解决方案2】:

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

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

【讨论】:

  • 感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-07-23
  • 2011-06-25
  • 2021-09-08
  • 2021-12-03
  • 1970-01-01
  • 2011-08-05
  • 2016-11-21
  • 1970-01-01
相关资源
最近更新 更多