从Lua调用函数时如何处理C ++异常? [英] How to handle C++ exceptions when calling functions from Lua?
问题描述
int PushHello(lua_State * L){
string str );
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.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:
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?Another problem that I have probably solved by compiling Lua as C++ is when
lua_pushlstring()
callslua_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屋!