c++ - 从 lua_pcall(L, 0, 0, 0) 获取所有错误

标签 c++ lua lua-api

是否可以从C/C++获取lua栈中的所有错误?这是我试过的

C++

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);

    if (luaL_loadfile(L, "LuaBridgeScript.lua"))
    {
        throw std::runtime_error("Unable to find lua file");
    }

    int error = lua_pcall(L, 0, 0, 0);
    while (error && lua_gettop(L))
    {
        std::cout << "stack = " << lua_gettop(L) << "\n";
        std::cout << "error = " << error << "\n";
        std::cout << "message = " << lua_tostring(L, -1) << "\n";
        lua_pop(L, 1);
        error = lua_pcall(L, 0, 0, 0);
    }
}

卢阿:

printMessage("hi")
printMessage2("hi2")

输出:

stack = 1
error = 2
message = LuaBridgeScript.lua:1: attempt to call global 'printMessage' <a nil value>

我也尝试过循环,即使堆栈大小为 0 或负数,但我不明白堆栈怎么会是负数,并且程序在几次尝试后崩溃。

最佳答案

将我的评论总结成一个答案:

根据 Lua docslua_pcall 上,pcall 在成功( block 结束)或抛出第一个错误时返回。所以在后一种情况下,它会将仅一个 消息推送到堆栈。在第一个错误之后它永远不会继续执行。

您要实现的目标是检查文件中可能存在的错误。在像 C 这样的静态类型语言中,每个变量都必须在编译时定义,因此编译器可以发现调用不存在函数的实例。

然而,Lua 是一种动态类型语言,其中变量没有类型,而是值的占位符(确实有类型)。这意味着,Lua 无法提前判断 printMessage 是函数、字符串、值还是不存在 (nil)。只有在运行时即将调用变量时,Lua 才会检查其类型。

因此不可能以这种方式实现您想要的。在第一个未处理的错误之后运行代码也是毫无意义的,因为该错误可能会使后续片段中的假设无效(例如关于不存在的函数应该设置的全局变量)——这将是一团糟。

至于语法错误,这些通常是在编译源文件时发现的,即在加载时发现。但是,Lua 解析器在第一次遇到语法错误时停止。这是因为很多时候一个地方的语法错误会使它后面的所有内容都无效。正如 Etan 在他的评论中指出的那样,许多解析器报告后续错误,一旦您修复了它们之前的错误,这些错误就会消失或改变。对于像 MSVS 中的重量级解析器也是如此。

关于c++ - 从 lua_pcall(L, 0, 0, 0) 获取所有错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25283297/

相关文章:

c++ - Luabridge 对 LuaRef 数据的弱引用

Lua C API : Delete metatable created with luaL_newmetatable?

c - C 中的嵌套 Lua 元表

c - 如何在尾调用中保留 Lua 函数闭包?

c++ - 内联汇编会影响可移植性吗?

c++ - 使用 char* 运算符的随机输出

c++ - 运行不包括 Catch2 中特定标记的单元测试

string - Lua 中带有单反斜杠 (!) 的字符串需要转义或替换 - 如何操作?

c++ - 如何查找lua堆栈中有多少项(值)

c++ - C++中RAII和智能指针的区别