【问题标题】:C++ & Lua - attempt to index a nil value errorC++ & Lua - 尝试索引一个零值错误
【发布时间】:2014-01-07 01:55:13
【问题描述】:

我目前正在学习如何使 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

【问题讨论】:

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


    【解决方案1】:
    void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
    

    将数组 l 中的所有函数(参见 luaL_Reg)注册到堆栈顶部的表中(在可选上值下方,参见下一个)。


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

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

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

    luaL_setfuncs 之前插入luaL_newlibtable(L, _funcs),或者改用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
    

    【讨论】:

    • 而且lua_register也没有错,如果你需要“只导出一个函数”。
    【解决方案2】:

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

    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

    【讨论】:

    • 那是我尝试过的其中一件事,嗯......它没有帮助
    • 不,这不是发生的事情。聚合初始化将多余的元素“初始化为 0”(算术类型初始化为 0,指针初始化为 nullptr,就好像它们是 static)。
    【解决方案3】:

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

    我将luaL_setfuncs() 更改为lua_register(),现在似乎一切正常。出了什么问题 - 我不知道。

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

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

    【讨论】:

    • 重新阅读 luaL_setfuncs 的文档。它不会将函数放入全局表中;您需要在堆栈顶部有一个表才能写入。
    • 我是不是应该先做那张桌子,然后再打电话给luaL_setfuncs()?文档非常模糊,我什至找不到luaL_setfuncs() 的示例。
    • luaL_setfuncs 的描述中是否有让您感到困惑的特定部分?
    • @Seth 基于文档我认为您可能必须使用 newlib 查看我编辑的答案
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 2015-10-18
    • 2016-09-19
    • 1970-01-01
    相关资源
    最近更新 更多