如何在交互终端上从c++/lua项目的lua文件中调用函数?

我在阅读一个由c++和lua组成的项目的一些源代码,它们通过luabind相互交织。

有一个la.lua文件,在其中有一个函数exec(arg)。这个lua文件还使用其他lua文件中的函数/变量,因此它在开头有如下的语句

module(..., package.seeall);
print("Loading "..debug.getinfo(1).source.."...")
require "client_config"

现在我想从交互终端(在Linux上)运行la.exec(),但我得到了错误,例如

attempt to index global 'lg' (a nil value)

如果我要导入la.lua,我会得到

require "la"
Loading @./la.lua...
./la.lua:68: attempt to index global 'ld' (a nil value)
stack traceback:
./lg.lua:68: in main chunk
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?

我该怎么办?

点赞
用户805875
用户805875

好的,可能发生了什么问题呢?

(根据您提供的信息,以下是一些普遍的猜测……)

一个可能是你缺少依赖项,因为文件没有正确地require它们所依赖的所有内容。(如果A依赖并且require B然后是C,C依赖B但不会指明要require它,因为它是由A隐式加载的,直接加载C将失败。)因此,如果你花费一些时间去跟踪和修复依赖项,事情可能会突然开始工作。

(然而,这也许是不可能的,这取决于模块是如何编写的。例如,除非你在加载子模块之前设置package.loaded["foo"]为_foo_的模块表,否则这些子模块将无法require"foo"。(幸运的是,module执行了这个操作,在没有module的新代码中,很容易忘记这个操作——然后你将陷入无尽循环中(直到堆栈溢出),foo加载其他模块,其他模块又加载_foo_,等等)此外,在“修复”它们以便在解释器中加载的过程中,你可能会无意间破坏程序/库在正常运行时使用的加载顺序,在你再次尝试正常运行它时才会注意到。因此,修复依赖项可能需要太多时间。你仍然可以追踪足够的依赖项来构建一个长的lua -lfoo-lbar_……一次性依赖项列表,这可能会让事情开始运行,但不要依赖它。)

另一个可能性是C(++)模块缺少提供的部分。如果它们是按照Lua库的风格编写的(即它们有luaopen_FOO),它们可能会在解释器中加载。(如果我没记错,对于C++来说这是不太可能的,因为它期望主程序是C++-aware的,但lua通常(始终?)是纯粹的C。)这些模块可能不是那样工作的,需要以其他方式加载。还有一种可能性,就是主程序在它创建的Lua状态中预定义了一些内容,这意味着没有模块可以加载以获取这些内容。


虽然上述情况还有一些变化,但这些就是所有的一般分类。如果你认为自己的问题是第一个(仅仅是缺少依赖项信息),也许你应该再花一些时间去解决它,因为你有很大的机会使它工作。如果你认为是后两种情况之一,那么你很可能无法使它工作(至少不能直接)。

你可能可以通过修补程序来绕过这个问题,以打开一个REPL,然后从那里做你想做的事情。(最简单的方法是调用debug.debug()。它功能有限(无多行,无隐式return,错误信息较差),但如果你需要/想要更好的东西,一个行为非常类似于正常Lua REPL的东西可以用 ~30行的Lua代码编写。)

2017-02-18 07:29:06