为什么在调用luaL_error时,c++对象析构函数不被调用?

我有一段代码如下:

class Test
{
public:
    Test(){ printf(">>> Test()\n"); }
    ~Test(){ printf(">>> ~Test()\n"); }
};

int myFunc(lua_State* L)
{
    Test t;
    luaL_error(L, "error");
    return 0;
}

我知道当使用 C 编译器编译 Lua 时,它使用 longjmp 来触发错误。因此,我使用 C++ 编译器编译它,以便使用 C++ 异常来处理错误,并且即使抛出错误,析构函数也应该被调用。但是我的问题是对象的析构函数没有被调用。

然而,以下代码是有效的(析构函数被调用):

int myFunc(lua_State* L)
{
    Test t;
    throw(1) // just for testing
    return 0;
}

为什么会发生这种情况呢?我确定 LUAI_THROW 宏被解释为 throw 关键词。

点赞
用户3514014
用户3514014

luaL_error() 函数将调用 exit(),从而取消整个程序的执行! 然后析构函数不会被调用,因为 Test t 所处的作用域没有结束。您应该使用不同的功能以便从错误中恢复。

从 Lua 调用错误该如何处理? 我认为您需要使用 lua_cpcall 进行受保护的调用来绕过这个错误退出功能!

2014-04-28 09:19:23
用户1180380
用户1180380

根本原因与 Visual C++ 编译器中的异常处理模式有关。我使用了带有 extern "C" 修饰符的 Lua 函数(例如 luaL_error)以防止编译器进行名称翻译。默认的异常处理模式是 /EHsc,它假定 extern "C" 函数不会抛出异常。因此,无法捕获异常。解决方法是将 /EHsc 更改为 /EHs。

如需了解更多信息,请参阅 http://msdn.microsoft.com/en-us/library/1deeycx5.aspx

2014-05-05 06:19:23