lua5.3與C++交互學習(二)


C++中對lua協程和返回值的處理

lua語言中, 在coroutine的resume和yield之間可以相互傳遞參數, 最近研究了下lua_resume和lua_yield 兩個函數, 同樣利用這兩個函數可以通過棧在C++與lua之間很方便的交換數據;這裏給出一個簡單的示例;

1.lua中寫一個協程函數

function CorTest()
  print("coroutine begin")
  local re = coroutine.yield(100, "hello c++")  // 往棧中傳參數以便C++能獲取
  print("lua coroutine continue: " .. re)  // 從c中lua_resume傳回來的參數是者的re
  Stop("call c yield!")  // 調用c的掛起函數
  print("coroutine continue after yield")
  print("coroutine end")
end

這裏嘗試了lua的yield和C++的lua_yield:
2. 在C++中寫一個掛起函數註冊到lua中使用

static int Stop(lua_State* L)
{
  // 會傳一個參數進來
  const char* str = lua_tostring(L,-1);
  print("C Stop: %s\n", str);
  //將這個值再次壓入棧中
  lua_pushstring(L,str);
  lua_yield(L,1);
  assert(0);   // 協程恢復後是不會回到這邊的, 而是直接回到lua中Stop()後一句, 原因是C++棧已經釋放
  return 0;
}

3.這裏直接在C中創建協程:

// 參數corName是在lua中寫的協程函數
lua_State* CreateCoroutine(lua_State* gL, const char* corName)
{
  lua_checkstack(L,10);  // 10個是隨便寫的一個數字, 不影響
  lua_State* lt = lua_newthread(gL);
  lua_getglobal(lt, corName);  // 協程函數入棧
  return lt;
}

4.這裏在main函數中進行主要處理:

int main()
{
  // 省略前面的lua初始化代碼
  /**....**/
  lua_register(L,"Wait",Wait);
  lua_State* lt = CreateCoroutine(L,"CorTest"); 
  int re = lua_resume(lt, L, 0);  // 這次傳0個參數(因爲CorTest沒有參數)
  if(re != LUA_YIELD)
    printf("ERROR");
  //   lua掛起後, 穿回來100, 和hello C++兩個值, 可以lua_gettop(lt)看個數
  int rint = luaL_checknumber(lt, -2);
  const char* str = lua_tostring(lt, -1);
  printf("stack value: %d,  %s\n", rint, str);  // ⇒ 100, hello C++
  // 這次恢復協程時傳入參數, 參數壓棧, lua中就是對應返回值local re
  lua_pushstring(lt, " from c++");
  re = lua_resume(lt, L, 1);
  // 掛起後是在Stop()函數中傳入了一個"call c yield!"
  printf("%s\n",lua_tostring(lt,-1));
  re = lua_resume(lt, L, 0); // 這裏無法傳值回去lua了,因爲Stop的棧已經被釋放 ,而是直接運行lua中Stop的後一句
}

輸出結果如下:

coroutine begin
100, hello C++
coroutine contine ,    from C++
C Stop: call yield
coroutine continue after C yield,  from c++ 
lua end
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章