Как распечатать ошибки в консоли с C API для Lua

Я искал высоко и низко способ обработки ошибок с помощью C API для 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 и показывать сообщения в консоли?

2 ответа

Решение

Первый пример кода - один из правильных способов борьбы с ошибками в 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-е издание)".

У меня был точно такой же вопрос, и ответ Кэтвелл не ответил на него полностью. То, что я изначально делал в своей программе, было просто вызовом

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));
  }
  ...
}
Другие вопросы по тегам