从Lua调用函数时如何处理C ++异常? [英] How to handle C++ exceptions when calling functions from Lua?

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

问题描述

我有一个工作的C ++函数,我可以从Lua调用。在这里演示我的问题是一个例子:

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

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



这是我的两个问题:


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


  2. 另外一个问题,我可能通过将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.data(),str.length());
return 1;
}

但是,这样非常丑陋,容易出错,因为 try / catch 需要添加到很多地方。它可以做为一个宏,并放在可以抛出的每个命令上,但这不会更好。

解决方案

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

 模板< lua_CFunction func> 
int SafeFunction(lua_State * L){
int result = 0;
try {
result = func(L);
}
//将描述转换为lua_error
catch(exception& e){
luaL_error(L,e.what());
}
// rethrow lua错误 - C ++ Lua throws lua_longjmp *
catch(lua_longjmp *){
throw;
}
//任何其他异常作为lua_error没有描述
catch(...){
luaL_error(L,未知错误);
}

返回结果;
}

你觉得怎么样?你有什么问题吗?


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.

Here are my two problems:

  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?

  2. 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?

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;
}

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.

解决方案

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 ++异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆