C ++& Lua - 尝试索引零值错误

时间:2014-01-07 01:55:14

标签: c++ visual-c++ lua visual-studio-2013

我目前正在学习如何让Lua使用C ++,我偶然发现了这个问题。 这是我正在使用的小应用程序:

#include <lua.5.2.3\src\lua.hpp>
#include <iostream>
#include <string>

int pluacall(lua_State *L){
    std::cout << "Called from inside Lua." << std::endl;
    return 0;
}

int main(){
    std::string x;
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    luaL_Reg _funcs[] = { { "CppFunc", pluacall }, {} };

    if (luaL_dofile(L, "test.lua")){
        std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
        lua_pop(L, 1);
    }

    luaL_setfuncs(L, _funcs, 0);

    lua_getglobal(L, "sup");
    if (lua_pcall(L, 0, 0, 0)){
        std::cout << "Error: " << lua_tostring(L, -1) << std::endl;
        lua_pop(L, 1);
    }


    std::cout << "Test";
    std::getline(std::cin, x);

    lua_close(L);
    return 0;
}

在我添加luaL_setfuncs(...)之前,所有工作都完美无缺。

现在应用程序崩溃并出现以下错误:

PANIC: Unprotected error in call to Lua API (attempt to index a nil value)

我会完全诚实,我完全不知道为什么它不起作用或这个错误甚至意味着什么(谷歌今天不是我的朋友)。有什么想法吗?

可能还值得一提的是,我没有将Lua库与我的应用程序链接,我将它们编译在一起(所有Lua源都添加到项目中)

编辑:这是我用

测试它的Lua脚本
function sup()
    io.write("Hey.\n")
    CppFunc()
    return 1
end

3 个答案:

答案 0 :(得分:2)

void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);

将数组l中的所有函数(参见luaL_Reg)注册到堆栈顶部的表格中(在可选的upvalues下面,见下文)。


void luaL_newlib (lua_State *L, const luaL_Reg *l);

创建一个新表并在列表l中注册函数。它实现为以下宏:

 (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))

luaL_newlibtable(L, _funcs)之前插入luaL_setfuncs,或使用luaL_newlib(L, _funcs)。如果要将函数注册到单独的表中,而不是注册到全局命名空间,则可以使用以下方法:

lua_pushvalue(L, LUA_GLOBALSINDEX); // push _G table
luaL_setfuncs(L, _funcs, 0); // set funcs on _G
lua_pop(L, 1); // pop _G

答案 1 :(得分:1)

尝试显式设置终止funcs数组的sentinel:

luaL_Reg _funcs[] = { { "CppFunc", pluacall }, {NULL, NULL} };

我不认为编译器给它们默认的0值(但我不是100%),所以如果你不设置它们,你最终会得到垃圾指针因此崩溃。

在评论后编辑上述内容无效:

如果这不是问题,请尝试使用luaL_newlib而不是luaL_setfuncs:它似乎使用luaL_newlibtable,它在堆栈上创建一个表,然后调用setfuncs来注册函数:

luaL_newlib(L, _funcs);

(我很惊讶找到关于此的明确文档/示例是多么困难)。见very good answer to similar question on SO

答案 2 :(得分:0)

所以我并没有完全解决这个问题我的想法,但是它总比没有好。

我将luaL_setfuncs()更改为lua_register(),现在一切似乎都有效。问题是什么 - 我不知道。

我认为luaL_setfuncs()是现在用Lua注册C函数的优先方式,它不起作用所以我必须坚持通过lua_register()注册所有内容。

如果我在这个问题上得到更多信息,我会编辑这篇文章。