4

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

4

2 回答 2

5

第一个代码示例是在 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:

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 工作原理的更多信息,我鼓励您阅读“Lua 编程(第 4 版)”一书中的专门部分。

于 2017-05-20T11:02:30.377 回答
4

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

luaL_dofile(L, "example.lua");

发生错误时什么也没发生。

“如果你从标准的 Lua 解释器中调用它……”是一个很好的线索。因此,我查看了 main inluac.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-19T11:08:02.080 回答