Я искал высоко и низко способ обработки ошибок с помощью 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 и показывать сообщения в консоли?
Первый пример кода — один из правильных способов борьбы с ошибками в 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));
}
...
}