• <bdo id='VjZek'></bdo><ul id='VjZek'></ul>
    <i id='VjZek'><tr id='VjZek'><dt id='VjZek'><q id='VjZek'><span id='VjZek'><b id='VjZek'><form id='VjZek'><ins id='VjZek'></ins><ul id='VjZek'></ul><sub id='VjZek'></sub></form><legend id='VjZek'></legend><bdo id='VjZek'><pre id='VjZek'><center id='VjZek'></center></pre></bdo></b><th id='VjZek'></th></span></q></dt></tr></i><div id='VjZek'><tfoot id='VjZek'></tfoot><dl id='VjZek'><fieldset id='VjZek'></fieldset></dl></div>

      <legend id='VjZek'><style id='VjZek'><dir id='VjZek'><q id='VjZek'></q></dir></style></legend>

        <small id='VjZek'></small><noframes id='VjZek'>

      1. <tfoot id='VjZek'></tfoot>

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

        时间:2023-09-27
      2. <legend id='ODi4h'><style id='ODi4h'><dir id='ODi4h'><q id='ODi4h'></q></dir></style></legend>

            <i id='ODi4h'><tr id='ODi4h'><dt id='ODi4h'><q id='ODi4h'><span id='ODi4h'><b id='ODi4h'><form id='ODi4h'><ins id='ODi4h'></ins><ul id='ODi4h'></ul><sub id='ODi4h'></sub></form><legend id='ODi4h'></legend><bdo id='ODi4h'><pre id='ODi4h'><center id='ODi4h'></center></pre></bdo></b><th id='ODi4h'></th></span></q></dt></tr></i><div id='ODi4h'><tfoot id='ODi4h'></tfoot><dl id='ODi4h'><fieldset id='ODi4h'></fieldset></dl></div>
            1. <tfoot id='ODi4h'></tfoot>

              <small id='ODi4h'></small><noframes id='ODi4h'>

                <tbody id='ODi4h'></tbody>

                <bdo id='ODi4h'></bdo><ul id='ODi4h'></ul>

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

                  上一篇:使用句柄从 .lua 调用 lua 函数? 下一篇:如何使用可变参数模板制作通用的 Lua 函数包装器?

                  相关文章

                    <i id='a8wnx'><tr id='a8wnx'><dt id='a8wnx'><q id='a8wnx'><span id='a8wnx'><b id='a8wnx'><form id='a8wnx'><ins id='a8wnx'></ins><ul id='a8wnx'></ul><sub id='a8wnx'></sub></form><legend id='a8wnx'></legend><bdo id='a8wnx'><pre id='a8wnx'><center id='a8wnx'></center></pre></bdo></b><th id='a8wnx'></th></span></q></dt></tr></i><div id='a8wnx'><tfoot id='a8wnx'></tfoot><dl id='a8wnx'><fieldset id='a8wnx'></fieldset></dl></div>
                    • <bdo id='a8wnx'></bdo><ul id='a8wnx'></ul>
                  1. <tfoot id='a8wnx'></tfoot>

                      <legend id='a8wnx'><style id='a8wnx'><dir id='a8wnx'><q id='a8wnx'></q></dir></style></legend>

                      <small id='a8wnx'></small><noframes id='a8wnx'>