当前位置:编程学习 > C/C++ >>

luabind使用coroutine时的一处善意提示导致的BUG

以下代码使用luabind进行lua的coroutine测试
   1: void ScriptManagedChannel::OnServiceInitialize()
   2: {   
   3:     try
   4:     {       
   5:         mThread = lua_newthread( GScriptScriptContext->GetVM() );
   6: 
   7:         luabind::resume_function<void>( mThread, "ScriptMain", this );
   8: 
   9:         Resume();
  10:     }
  11:     catch (std::exception& e)
  12:     {
  13:         const char* ErrorMsg = lua_tostring( GScriptScriptContext->GetVM(), -1 );           
  14:         printf("%s\n", e.what() );
  15:     }
  16: 
  17:    
  18: }
  19: 
  20: void ScriptManagedChannel::Resume( )
  21: {
  22:     luabind::resume<void>( mThread );
  23: }
  24: 
  25: void ScriptManagedChannel::StopTest( )
  26: {
  27:     lua_yield( mThread, 0 );
  28: }
  29: 
  30: 
代码中, mThread类型为lua_State*类型
GScriptScriptContext->GetVM()是加载了代码的lua_State*
StopTest为注册为ScriptManagedChannel类成员函数到lua中的定义
接下来看lua端的测试代码:
   1: function ScriptMain( Channel )
   2: 
   3:    
   4:     for i = 1, 5 do
   5:    
   6:     print("done", i)
   7:    
   8:     Channel:StopTest( )
   9:    
  10:    
  11:    
  12:     end
  13: end
刚开始,在测试代码时, lua中有个手误而造成的错误, 导致C++代码运行到第7行时弹出assert
位于:luabind-0.9.1\luabind\detail\call_function.hpp 第264行,对应以下代码第13行
   1: ~proxy_function_void_caller()
   2: {
   3:     if (m_called) return;
   4: 
   5:     m_called = true;
   6:     lua_State* L = m_state;
   7: 
   8:     int top = lua_gettop(L);
   9: 
  10:     push_args_from_tuple<1>::apply(L, m_args);
  11:     if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
  12:     {
  13:         assert(lua_gettop(L) == top - m_params + 1);
  14: 
  15: NO_EXCEPTIONS
  16:         throw luabind::error(L);
  17: #else
  18:         error_callback_fun e = get_error_callback();
  19:         if (e) e(L);
  20:    
  21:         assert(0 && "the lua function threw an error and exceptions are disabled."
  22:                 " If you want to handle the error you can use luabind::set_error_callback()");
  23:         std::terminate();
  24: #endif
  25:     }
  26:     // pops the return values from the function call
  27:     stack_pop pop(L, lua_gettop(L) - top + m_params);
  28: }
11行代码中调用的是lua_resume, 返回的是运行错误, 但是被13行的assert挡住了, 无法通过第16行抛出异常被外面捕获.
因此,尝试注释第13行, 再测试, 可以在lua抛出错误后, 在栈顶捕获到coroutine函数resume时报出的错误信息.问题解决
 
对于lua的coroutine, 网上资料不多, 这里有一篇比较详细的代码
我比较疑惑的是, 有没有必要将代码在dofile或者dobuffer时, 必须传入newthread出的state? 如果还是传入原始的state会有什么影响?
欢迎各位有此经验的讨论

 

摘自  战魂小筑 
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,