【问题标题】:How to print out errors in the console with the C API for Lua如何使用 Lua 的 C API 在控制台中打印错误
【发布时间】:2017-10-20 08:55:43
【问题描述】:

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

【问题讨论】:

    标签: c++ c error-handling lua lua-c++-connection


    【解决方案1】:

    第一个代码示例是在 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_checklstring、luaL_argcheck 或 luaL_argerror 之一来改进,而不是直接使用 luaL_error。

    要详细了解 C API 的工作原理,我建议您阅读“Lua 编程(第 4 版)”一书中的专门部分。

    【讨论】:

      【解决方案2】:

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

      luaL_dofile(L, "example.lua");
      

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

      “如果你从标准的 Lua 解释器中调用它……” 是一个很好的线索。所以我查看了 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));
        }
        ...
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-16
        • 2015-08-04
        • 1970-01-01
        • 1970-01-01
        • 2018-10-03
        相关资源
        最近更新 更多