加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 00:22:45 所属栏目:大数据 来源:网络整理
导读:我有一个工作的C函数,我可以从Lua调用。在这里演示我的问题就是一个例子: int PushHello(lua_State *L){ string str("Hello"); lua_pushlstring(L,str.data(),str.length()); return 1;} 注意:我知道我不必在那里使用字符串变量,但它是在那里演示的问题
我有一个工作的C函数,我可以从Lua调用。在这里演示我的问题就是一个例子:
int PushHello(lua_State *L){
    string str("Hello");
    lua_pushlstring(L,str.data(),str.length());
    return 1;
}

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

这是我的两个问题:

>当我从Lua中调用这个函数时,string构造函数可能会抛出异常。那是问题吗? Lua会妥善处理它,放开Lua堆吗?我不这么认为我该如何解决呢?我需要添加所有这些代码的try / catch,并将异常转换为lua_error?是不是有更好的解决方案?
>另一个可能通过将Lua编译为C解决的问题是当lua_pushlstring()调用lua_error()时,如果使用longjmp,则不会调用string析构函数。通过编译为C并抛出异常而不是使用longjmp来解决问题?

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

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

但是这很难看,因为try / catch需要添加到很多地方。它可以做为一个宏,并放在可以抛出的每个命令,但这不会更好。

解决方法

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

你怎么看待这件事?你有什么问题吗?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读