Lua:加载文件后全局函数失败

时间:2011-07-19 00:31:46

标签: c++ lua

我正在尝试调用名为test2.lua的lua文件中的函数 这是test2.lua的内容:

function abc(path)
 t = {}
 table.insert(t, "a")
 return t
end

正如您所看到的,它只需要一个输入并返回一个字符串。

这是我的C代码。这很简单。然而我调用getglobal以调用该函数不起作用... lua_getglobal说我测试时它不是一个函数...这是什么原因?不应该abc是源文件中可返回的全局函数吗?那么为什么它只能为这个全局找到零?

L = lua_open();
luaL_openlibs(L);
luaL_loadfile(L, "src/test2.lua");

lua_getglobal(L, "abc");

lua_pushstring(L, "coollll");

int error = 0;
if ((error = lua_pcall(L, 1, 1, 0)) == 0)
{
    std::cout << "cool";
}

编辑:

调用lua_getglobal导致我的程序无论使用loadfile还是dofile都会破坏控制...任何想法为什么?

lua_getglobal crashing program

2 个答案:

答案 0 :(得分:8)

函数luaL_loadfile()读取,解析和编译命名的Lua文件。它不执行任何内容。这在您的情况下很重要,因为语句function abc(path) ... end在执行之前没有可见的效果。您使用它的function关键字等同于编写

abc = function(path)  
  t = {}
  table.insert(t, "a")
  return t
end

在这种形式中,更清楚的是,在代码执行之前,名为abc的变量实际上没有赋值。

luaL_loadfile()返回时,它已在Lua堆栈的顶部推送了一个匿名函数,该函数是编译文件的结果。你需要打电话给它,lua_pcall()就可以了。将luaL_loadfile()的引用替换为:

if (luaL_loadfile(L, "src/test2.lua") || lua_pcall(L, 0, LUA_MULTRET, 0)) {
    // do something with the error
} 

此时,test2.lua已被执行,它定义的任何函数或其修改的其他全局变量都可用。

这是一个很常见的习惯用法,提供函数luaL_dofile()来按名称加载和调用文件。

您的代码中存在第二个更微妙的问题。函数abc()使用名为t的变量,但您应该知道使用的t是全局变量。您可能打算在local t = {}的顶部写下abc()

答案 1 :(得分:3)

仅仅调用luaL_loadfile是不够的:这会将一个块放入堆栈。要么跟进luaL_[p]call以执行块(从而使函数可用),要么使用luaL_dofile