从Lua调用函数时如何处理C++异常?

2023-09-27C/C++开发问题
3

本文介绍了从Lua调用函数时如何处理C++异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个可以从 Lua 调用的 C++ 函数.为了证明我的问题,这里有一个例子:

I have a working C++ function that I am able to call from Lua. To demonstrate my problem here is an example:

int PushHello(lua_State *L){
    string str("Hello");
    lua_pushlstring(L, str.data(), str.length());
    return 1;
}

注意:我知道我不必在那里使用字符串变量,但它是用来演示问题的.

Note: I know I don't have to use string variable there, but it is there to demonstrate the problem.

这是我的两个问题:

  1. 当我从 Lua 字符串构造函数调用这个函数时,可能会抛出异常.那是问题吗?Lua 会处理它并正确展开 Lua 堆栈吗?我不这么认为.我该如何解决?我是否需要在所有这些代码周围添加 try/catch 并将异常转换为 lua_error?没有更好的解决方案吗?

  1. When I call this function from Lua string constructor may throw an exception. Is that a problem? Will Lua handle it and unwind the Lua stack properly? I don't think so. How can I solve that? Do I need to add try/catch around all such code and convert the exception to lua_error? Is not there a better solution?

我可能通过将 Lua 编译为 C++ 解决的另一个问题是 lua_pushlstring() 调用 lua_error() 如果 longjmp 是字符串析构函数,则不会调用它用过的.问题是不是用longjmp编译成C++抛出异常解决了?

Another problem that I have probably solved by compiling Lua as C++ is when lua_pushlstring() calls lua_error() string destructor would not be called if longjmp was used. Is the problem solved by compiling as C++ and throwing exceptions instead of using longjmp?

澄清一下,我可以看到问题 1 的可能解决方案是:

To clarify, possible solution I can see to problem 1 would be this:

int PushHello(lua_State *L){
    string str;
    try{
        str.assign("Hello");
    catch(exception &e){
        luaL_error(L, e.what());
    }
    lua_pushlstring(L, str.data(), str.length());
    return 1;
}

但这是非常丑陋且容易出错的,因为 try/catch 需要添加到许多地方.它可以作为一个宏来完成,并放置每个可以抛出的命令,但这不会更好.

But that is very ugly and error prone as try/catch would need to be added to many places. It could be done as a macro and put around every command that can throw, but that would not be much nicer.

推荐答案

我找到了一个合理的解决方案.问题是它是否正确.而不是导出(或通过 lua_cpcall 调用)原始函数 int PushHello(lua_State *L) 一个包装器 int SafeFunction(lua_State *L) 被导出/调用.包装器看起来像:

I have found a reasonable solution. The question is whether it is correct. Instead of exporting (or calling via lua_cpcall) the original function int PushHello(lua_State *L) a wrapper int SafeFunction<PushHello>(lua_State *L) is exported/called. The wrapper looks like:

template<lua_CFunction func>
int SafeFunction(lua_State *L){
    int result = 0;
    try{
        result = func(L);
    }
    // transform exception with description into lua_error
    catch(exception &e){
        luaL_error(L, e.what());
    }
    // rethrow lua error - C++ Lua throws lua_longjmp*
    catch(lua_longjmp*){
        throw;
    }
    // any other exception as lua_error with no description
    catch(...){
        luaL_error(L, "Unknown error");
    }

    return result;
}

你怎么看?你看到什么问题了吗?

What do you think about it? Do you see any problems?

这篇关于从Lua调用函数时如何处理C++异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

无法访问 C++ std::set 中对象的非常量成员函数
Unable to access non-const member functions of objects in C++ std::set(无法访问 C++ std::set 中对象的非常量成员函数)...
2024-08-14 C/C++开发问题
17

从 lambda 构造 std::function 参数
Constructing std::function argument from lambda(从 lambda 构造 std::function 参数)...
2024-08-14 C/C++开发问题
25

STL BigInt 类实现
STL BigInt class implementation(STL BigInt 类实现)...
2024-08-14 C/C++开发问题
3

使用 std::atomic 和 std::condition_variable 同步不可靠
Sync is unreliable using std::atomic and std::condition_variable(使用 std::atomic 和 std::condition_variable 同步不可靠)...
2024-08-14 C/C++开发问题
17

在 STL 中将列表元素移动到末尾
Move list element to the end in STL(在 STL 中将列表元素移动到末尾)...
2024-08-14 C/C++开发问题
9

为什么禁止对存储在 STL 容器中的类重载 operator&amp;()?
Why is overloading operatoramp;() prohibited for classes stored in STL containers?(为什么禁止对存储在 STL 容器中的类重载 operatoramp;()?)...
2024-08-14 C/C++开发问题
6