如何使用 C API for Lua 在控制台中打印出错误

How to print out errors in the console with the C API for Lua

我一直在四处寻找一种方法来处理 C API for Lua 的错误,并在控制台中简单地打印出来。虽然,我找不到一个有效的例子。我想做的就是:

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 进行错误处理并在控制台中显示消息的正确方法是什么?

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

您正在编写一个 C 函数来实现将公开给 Lua 的接口。它像这样工作 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 in other语言:

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

请注意,由于此错误是由无效的参数类型引起的,您的代码可能会通过使用 luaL_checkstring / luaL_checklstring, luaL_argcheck or luaL_argerror 之一而不是直接使用 luaL_error 来改进。

要了解有关 C API 工作原理的更多信息,我鼓励您阅读书中的专门部分 "Programming in Lua (4th edition)"。

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

luaL_dofile(L, "example.lua");

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

"If you call it from a standard Lua interpreter..." 是一个很好的线索。所以我查看了 luac.c 中的 main 以了解它的作用:

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));
  }
  ...
}