У меня есть такой код
class Test
{
public:
Test() {printf(">>> Test()\n");}
~Test() {printf(">>> ~Test()\n");}
}
int myFunc(lua_State *L)
{
Test t;
luaL_error(L, "error");
return 0;
}
Я знаю, когда lua соблюдает c complier, он использует longjmp, чтобы вызвать ошибку. Итак, я скомпилировал его с использованием компилятора c ++, чтобы он использовал исключение c ++ для обработки ошибок, и деструктор должен вызываться, даже если выдается ошибка. Но моя проблема в том, что деструктор объекта не вызывается.
Тем не менее, следующий код работает (деструктор называется)
int myFunc(lua_State *L)
{
Test t;
throw(1) // just for testing
return 0;
}
Почему это случилось? Я уверен, что макрос LUAI_THROW интерпретируется как ключевое слово throw.
Функция luaL_error () вызовет функцию exit (), которая отменяет все выполнение вашей программы! Тогда дескриптор не вызывается, потому что область действия Test t не заканчивается. Вы должны использовать другую функциональность, чтобы иметь возможность восстановиться после ошибки.
Как вы называете ошибку от lua? Я думаю, что вам нужно сделать защищенный вызов, используя lua_cpcall, чтобы обойти этот выход при ошибке!
Основная причина связана с режимом обработки исключений в компиляторе Visual C ++. Я использую функцию lua (например, luaL_error) с модификатором extern «C», чтобы компилятор не искажал имена. И режим обработки исключений по умолчанию — это / EHsc, в котором предполагается, что функция extern «C» не вызывает исключение. Таким образом, исключение не может быть поймано. Решением является изменение / EHsc на / EHs.
Для получения дополнительной информации, пожалуйста, обратитесь к http://msdn.microsoft.com/en-us/library/1deeycx5.aspx.