使用 Lua 的 C API 在控制台打印错误的方法

我一直在寻找一种使用 Lua 的 C API 处理错误并在控制台打印出它们的方法,但是我找不到一个有效的例子。我希望能够做到以下简单的事情:

static int test(lua_State *L)
{
  if(!lua_isstring(L, 1))
     return luaL_error(L, "This is not a valid string");
}

或者

static int test(lua_State *L)
{
    try
    {
        if (!lua_isstring(L, 1))
        {
            throw luaL_error(L, "This is not a valid string");
        }
    }
    catch (int e)
    {
        std::cout << "Error " << e << std::endl;
    }
}

但是到目前为止没有任何结果。正确的方法是什么?使用 LUA C API 处理错误并在控制台显示消息的正确方式是什么?

点赞
用户204011
用户204011

第一个代码示例是在 Lua 中处理错误的正确方法之一,但你似乎对它的工作方式感到困惑。

你正在编写一个实现将暴露给 Lua 的接口的 C 函数。它的工作方式类似于这样的 Lua 代码:

local function test(s)
    if type(s) ~= "string" then
        error("This is not a valid string")
    end
end

导致错误的代码不是 test 函数,而是调用它并传递无效参数的代码。

当 Lua 代码以无效方式调用该函数时(例如:test(42)),它将引发 Lua 错误,并将字符串作为错误消息。如果您从标准 Lua 解释器中调用它,它将停止程序,打印错误消息和堆栈跟踪。

如果你想在 Lua 代码中做一些其他的事情,例如只是打印错误消息,你可以使用 pcall 捕获错误,它的用法有点像其他语言中的 try/catch:

local ok, err_msg = pcall(test, 42)
if not ok then
    print(err_msg)
end

请注意,由于此错误是由无效的参数类型引起的,因此对于你的代码来说,使用 luaL_checkstring / luaL_checklstringluaL_argcheckluaL_argerror 之一代替 luaL_error 可能会更加优化。

如果您想了解有关 C API 的更多信息,我建议您阅读书籍“Programming in Lua(第四版)”中的专门章节。

2017-05-20 11:02:30
用户872616
用户872616

我有完全相同的问题,而catwell的回答并没有完全回答我的问题。我最初在我的程序中所做的只是调用

luaL_dofile(L, "example.lua");

发生错误时没有任何反应。

“如果您从标准Lua解释器中调用它……”是一个很好的提示。因此,我查看了luac.c中的主要部分:

if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));

请注意,luaL_dofile也会扩展到lua_pcall。因此,如果在完成该文件时引发错误,那么唯一发生的事情就是错误消息被推送到L的堆栈上。这是您的责任要做一些事情。

因此,我相应地修改了我的代码:

#include <stdio.h> // fprintf, stderr
#include <stdlib.h> // exit, EXIT_FAILURE
static void fatal(const char* message) {
  fprintf(stderr,"%s\n", message);
  exit(EXIT_FAILURE);
}
int main(void) {
  ...
  if (luaL_dofile(L, "example.lua") != LUA_OK) {
    fatal(lua_tostring(L,-1));
  }
  ...
}
2018-05-19 11:08:02