Lua: 在C++中将table如何传入到lua中

[cpp]  view plain  copy
  1. 例一是参考别人的:  

[cpp]  view plain  copy
  1. //定义函数(返回table)  
  2. int func_return_table(lua_State *L)  
  3. {  
  4.  lua_newtable(L);//创建一个表格,放在栈顶  
  5.  lua_pushstring(L, "mydata");//压入key  
  6.  lua_pushnumber(L,66);//压入value  
  7.  lua_settable(L,-3);//弹出key,value,并设置到table里面去  
  8.   
  9.  lua_pushstring(L, "subdata");//压入key  
  10.  lua_newtable(L);//压入value,也是一个table  
  11.  lua_pushstring(L, "mydata");//压入subtable的key  
  12.  lua_pushnumber(L,53);//value  
  13.  lua_settable(L,-3);//弹出key,value,并设置到subtable  
  14.   
  15.  lua_settable(L,-3);//这时候父table的位置还是-3,弹出key,value(subtable),并设置到table里去  
  16.  lua_pushstring(L, "mydata2");//同上  
  17.  lua_pushnumber(L,77);  
  18.  lua_settable(L,-3);  
  19.  return 1;//堆栈里现在就一个table.其他都被弹掉了。  
  20. }  
输出结构体:

[cpp]  view plain  copy
  1. {  
  2.      "mydata" = 66,  
  3.      "mydate2" = 77,  
  4.      "subdata" =   
  5.      {  
  6.           "mydata" = 53  
  7.      }  
  8. }  

这里算是一个嵌套的结构体了。

函数解释:

[cpp]  view plain  copy
  1. lua_settable(lua_State* L, int index)  

就是把表在lua堆栈中的值弹出来,index 是table 在堆栈中的位置,假如 table 在 -3, 则key 应该是 -2,value 是 -1

相当于 table[key] = value.

例二:

在工作中这里我想用一个类似数组的table,类似 tableaname[n].x

代码:

[cpp]  view plain  copy
  1. struct BattleResultDamageData  
  2. {  
  3.     Uint32 nIcon;  
  4.     Uint32 nDamage;  
  5.     Uint16 nPetPos;  
  6.     Uint16 nLv;  
  7.     Uint8  nStar;  
  8.     Uint8  nEvo;  
  9.     Uint8  nCurSkin;  
  10.     Uint8  nStage;  
  11. };  

[cpp]  view plain  copy
  1. static int luaGetBattleResultData(lua_State *L_)  
  2. {  
  3.     lua_newtable(L_); //创建一个表,放在栈顶  
  4.     int i = 1; //目的:类似tablename[i].id  
  5.     std::map<unsigned, BattleResultDamageData>::const_iterator map_it;  
  6.     for (map_it = SkillActObj::_BattleAtk.begin(); map_it != SkillActObj::_BattleAtk.end(); ++map_it,++i) //可忽略,目的遍历C++中的数据放在lua的table  
  7.     {  
  8.         lua_pushnumber(L_,i);  
  9.         lua_newtable(L_);  
  10.         lua_pushstring(L_,"id");  
  11.         lua_pushnumber(L_,map_it->first);  
  12.         lua_settable(L_,-3);//弹出key,value,并设置到table里面去  
  13.         lua_pushstring(L_,"dmg");  
  14.         lua_pushnumber(L_,map_it->second.nDamage);  
  15.         lua_settable(L_,-3);  
  16.         lua_pushstring(L_,"icon");  
  17.         lua_pushnumber(L_,map_it->second.nIcon);  
  18.         lua_settable(L_,-3);  
  19.         lua_pushstring(L_,"lv");  
  20.         lua_pushnumber(L_,map_it->second.nLv);  
  21.         lua_settable(L_,-3);  
  22.         lua_pushstring(L_,"star");  
  23.         lua_pushnumber(L_,map_it->second.nStar);  
  24.         lua_settable(L_,-3);  
  25.         lua_pushstring(L_,"evo");  
  26.         lua_pushnumber(L_,map_it->second.nEvo);  
  27.         lua_settable(L_,-3);  
  28.         lua_pushstring(L_,"pos");  
  29.         lua_pushnumber(L_,map_it->second.nPetPos);  
  30.         lua_settable(L_,-3);  
  31.         lua_pushstring(L_,"skin");  
  32.         lua_pushnumber(L_,map_it->second.nCurSkin);  
  33.         lua_settable(L_,-3);  
  34.   
  35.         lua_settable(L_,-3);  
  36.     }  
  37.         return 1;  
  38. }  

在lua代码中的使用:

[cpp]  view plain  copy
  1. local buffAtk = _G.getBattleResultData();  

打印的buffAtk这个table结构体信息:

[cpp]  view plain  copy
  1. <Info>0409-210505 654 Lookup local var buffAtk  
  2. <Info>0409-210505 654 name = buffAtk   type = table    value = 0CB685A0  
  3. <Info>0409-210505 654 name = buffAtk[1]    type = table    value = 06CCEA58  
  4. <Info>0409-210505 670 name = buffAtk[1][dmg]   type = number   value = 89298  
  5. <Info>0409-210505 670 name = buffAtk[1][skin]  type = number   value = 0  
  6. <Info>0409-210505 670 name = buffAtk[1][star]  type = number   value = 6  
  7. <Info>0409-210505 689 name = buffAtk[1][evo]   type = number   value = 10  
  8. <Info>0409-210505 692 name = buffAtk[1][id]    type = number   value = 25165827  
  9. <Info>0409-210505 693 name = buffAtk[1][lv]    type = number   value = 131  
  10. <Info>0409-210505 693 name = buffAtk[1][icon]  type = number   value = 1090  
  11. <Info>0409-210505 693 name = buffAtk[1][pos]   type = number   value = 19  
  12. <Info>0409-210505 693 name = buffAtk[2]    type = table    value = 0CC8C038  
  13. <Info>0409-210505 693 name = buffAtk[2][dmg]   type = number   value = 28726  
  14. <Info>0409-210505 693 name = buffAtk[2][skin]  type = number   value = 0  
  15. <Info>0409-210505 710 name = buffAtk[2][star]  type = number   value = 6  
  16. <Info>0409-210505 711 name = buffAtk[2][evo]   type = number   value = 12  
  17. <Info>0409-210505 711 name = buffAtk[2][id]    type = number   value = 25165828  
  18. <Info>0409-210505 711 name = buffAtk[2][lv]    type = number   value = 90  
  19. <Info>0409-210505 711 name = buffAtk[2][icon]  type = number   value = 1325  
  20. <Info>0409-210505 711 name = buffAtk[2][pos]   type = number   value = 51  
例三:

上例返回一个,这里我想返回两个tableaname[n].x
如:一个tablename1[n].x 与 另一个 tablename2[n].x

[cpp]  view plain  copy
  1. static int luaGetBattleResultData(lua_State *L_)  
  2. {  
  3.     lua_newtable(L_); // 建立一个table  
  4.     int i = 1;  
  5.     std::map<unsigned, BattleResultDamageData>::const_iterator map_it;  
  6.     for (map_it = SkillActObj::_BattleAtk.begin(); map_it != SkillActObj::_BattleAtk.end(); ++map_it,++i)  
  7.     {     
  8.         lua_pushnumber(L_,i);  
  9.         lua_newtable(L_);  
  10.         lua_pushstring(L_,"id");  
  11.         lua_pushnumber(L_,map_it->first);  
  12.         lua_settable(L_,-3);//弹出key,value,并设置到table里面去  
  13.         //...  
  14.         lua_pushstring(L_,"skin");  
  15.         lua_pushnumber(L_,map_it->second.nCurSkin);  
  16.         lua_settable(L_,-3);  
  17.   
  18.         lua_settable(L_,-3);  
  19.     }  
  20.   
  21.     lua_newtable(L_); //建立另一个table  
  22.     i = 1;  
  23.     for (map_it = SkillActObj::_BattleDef.begin(); map_it != SkillActObj::_BattleDef.end(); ++map_it,++i)  
  24.     {  
  25.         lua_pushnumber(L_,i);  
  26.         lua_newtable(L_);  
  27.         lua_pushstring(L_,"id");  
  28.         lua_pushnumber(L_,map_it->first);  
  29.         lua_settable(L_,-3);//弹出key,value,并设置到table里面去  
  30.         // ...  
  31.         lua_pushstring(L_,"skin");  
  32.         lua_pushnumber(L_,map_it->second.nCurSkin);  
  33.         lua_settable(L_,-3);  
  34.   
  35.         lua_settable(L_,-3);  
  36.     }  
  37.     return 2; // 返回这两个table  
  38. }  
在lua中调用:

[cpp]  view plain  copy
  1. local buffAtk, buffDef= _G.getBattleResultData();  
打印这两个table的信息:

[cpp]  view plain  copy
  1. <Info>0409-210505 654 Lookup local var buffAtk  
  2. <Info>0409-210505 654 name = buffAtk   type = table    value = 0CB685A0  
  3. <Info>0409-210505 654 name = buffAtk[1]    type = table    value = 06CCEA58  
  4. <Info>0409-210505 670 name = buffAtk[1][dmg]   type = number   value = 89298  
  5. <Info>0409-210505 670 name = buffAtk[1][skin]  type = number   value = 0  
  6. <Info>0409-210505 670 name = buffAtk[1][star]  type = number   value = 6  
  7. <Info>0409-210505 689 name = buffAtk[1][evo]   type = number   value = 10  
  8. <Info>0409-210505 692 name = buffAtk[1][id]    type = number   value = 25165827  
  9. <Info>0409-210505 693 name = buffAtk[1][lv]    type = number   value = 131  
  10. <Info>0409-210505 693 name = buffAtk[1][icon]  type = number   value = 1090  
  11. <Info>0409-210505 693 name = buffAtk[1][pos]   type = number   value = 19  
  12. <Info>0409-210505 693 name = buffAtk[2]    type = table    value = 0CC8C038  
  13. <Info>0409-210505 693 name = buffAtk[2][dmg]   type = number   value = 28726  
  14. <Info>0409-210505 693 name = buffAtk[2][skin]  type = number   value = 0  
  15. <Info>0409-210505 710 name = buffAtk[2][star]  type = number   value = 6  
  16. <Info>0409-210505 711 name = buffAtk[2][evo]   type = number   value = 12  
  17. <Info>0409-210505 711 name = buffAtk[2][id]    type = number   value = 25165828  
  18. <Info>0409-210505 711 name = buffAtk[2][lv]    type = number   value = 90  
  19. <Info>0409-210505 711 name = buffAtk[2][icon]  type = number   value = 1325  
  20. <Info>0409-210505 711 name = buffAtk[2][pos]   type = number   value = 51  
  21. <Info>0409-210505 711   

[cpp]  view plain  copy
  1. <Info>0409-212740 450 Lookup local var buffDef  
  2. <Info>0409-212740 451 name = buffDef   type = table    value = 0CDD1EB8  
  3. <Info>0409-212740 451 name = buffDef[1]    type = table    value = 0CEEFCA8  
  4. <Info>0409-212740 451 name = buffDef[1][dmg]   type = number   value = 1992  
  5. <Info>0409-212740 451 name = buffDef[1][skin]  type = number   value = 0  
  6. <Info>0409-212740 466 name = buffDef[1][star]  type = number   value = 1  
  7. <Info>0409-212740 466 name = buffDef[1][evo]   type = number   value = 4  
  8. <Info>0409-212740 466 name = buffDef[1][id]    type = number   value = 25165829  
  9. <Info>0409-212740 482 name = buffDef[1][lv]    type = number   value = 85  
  10. <Info>0409-212740 482 name = buffDef[1][icon]  type = number   value = 1005  
  11. <Info>0409-212740 482 name = buffDef[1][pos]   type = number   value = 2  
  12. <Info>0409-212740 482 name = buffDef[2]    type = table    value = 0CEED4D0  
  13. <Info>0409-212740 482 name = buffDef[2][dmg]   type = number   value = 2941  
  14. <Info>0409-212740 482 name = buffDef[2][skin]  type = number   value = 0  
  15. <Info>0409-212740 499 name = buffDef[2][star]  type = number   value = 2  
  16. <Info>0409-212740 499 name = buffDef[2][evo]   type = number   value = 6  
  17. <Info>0409-212740 499 name = buffDef[2][id]    type = number   value = 25165830  
  18. <Info>0409-212740 499 name = buffDef[2][lv]    type = number   value = 85  
  19. <Info>0409-212740 499 name = buffDef[2][icon]  type = number   value = 1075  
  20. <Info>0409-212740 499 name = buffDef[2][pos]   type = number   value = 16  
  21. <Info>0409-212740 499 name = buffDef[3]    type = table    value = 0D0E83A0  
  22. <Info>0409-212740 516 name = buffDef[3][dmg]   type = number   value = 308  
  23. <Info>0409-212740 519 name = buffDef[3][skin]  type = number   value = 1  
  24. <Info>0409-212740 521 name = buffDef[3][star]  type = number   value = 0  
  25. <Info>0409-212740 523 name = buffDef[3][evo]   type = number   value = 6  
  26. <Info>0409-212740 523 name = buffDef[3][id]    type = number   value = 25165831  
  27. <Info>0409-212740 523 name = buffDef[3][lv]    type = number   value = 85  
  28. <Info>0409-212740 523 name = buffDef[3][icon]  type = number   value = 1080  
  29. <Info>0409-212740 523 name = buffDef[3][pos]   type = number   value = 17  
  30. <Info>0409-212740 523 name = buffDef[4]    type = table    value = 0CD85A00  
  31. <Info>0409-212740 523 name = buffDef[4][dmg]   type = number   value = 792  
  32. <Info>0409-212740 539 name = buffDef[4][skin]  type = number   value = 0  
  33. <Info>0409-212740 539 name = buffDef[4][star]  type = number   value = 0  
  34. <Info>0409-212740 539 name = buffDef[4][evo]   type = number   value = 0  
  35. <Info>0409-212740 539 name = buffDef[4][id]    type = number   value = 25165832  
  36. <Info>0409-212740 539 name = buffDef[4][lv]    type = number   value = 85  
  37. <Info>0409-212740 539 name = buffDef[4][icon]  type = number   value = 1145  
  38. <Info>0409-212740 539 name = buffDef[4][pos]   type = number   value = 30  
  39. <Info>0409-212740 554 name = buffDef[5]    type = table    value = 0C7CF7F8  
  40. <Info>0409-212740 554 name = buffDef[5][dmg]   type = number   value = 1608  
  41. <Info>0409-212740 554 name = buffDef[5][skin]  type = number   value = 0  
  42. <Info>0409-212740 554 name = buffDef[5][star]  type = number   value = 2  
  43. <Info>0409-212740 554 name = buffDef[5][evo]   type = number   value = 4  
  44. <Info>0409-212740 554 name = buffDef[5][id]    type = number   value = 25165833  
  45. <Info>0409-212740 571 name = buffDef[5][lv]    type = number   value = 47  
  46. <Info>0409-212740 574 name = buffDef[5][icon]  type = number   value = 1090  
  47. <Info>0409-212740 577 name = buffDef[5][pos]   type = number   value = 19  
  48. <Info>0409-212740 578   

看到这,是不是感觉哪里不对?是不是感觉代码好臃肿?

下面是最最终优化后的代码:

[cpp]  view plain  copy
  1. static void setTableInt(lua_State *L_, const char *sKey, lua_Number nVal)  
  2. {  
  3.     lua_pushstring(L_, sKey);  
  4.     lua_pushnumber(L_, nVal);  
  5.     lua_settable(L_,-3);  
  6. }  
  7.   
  8. static void newDmgTable(lua_State *L_, unsigned nEntityId, const BattleResultDamageData &data)  
  9. {  
  10.     lua_newtable(L_);  
  11.     setTableInt(L_, "id", nEntityId);  
  12.     setTableInt(L_, "dmg", data.nDamage);  
  13.     setTableInt(L_, "icon", data.nIcon);  
  14.     setTableInt(L_, "lv", data.nLv);  
  15.     setTableInt(L_, "star", data.nStar);  
  16.     setTableInt(L_, "evo", data.nEvo);  
  17.     setTableInt(L_, "pos", data.nPetPos);  
  18.     setTableInt(L_, "skin", data.nCurSkin);  
  19. }  
  20.   
  21. static int luaGetBattleResultData(lua_State *L_)  
  22. {  
  23.     std::map<unsigned, BattleResultDamageData> *datas[] = {&SkillActObj::_BattleAtk, &SkillActObj::_BattleDef};  
  24.     for (unsigned i = 0; i < 2; ++i)   
  25.     {  
  26.         lua_newtable(L_);   //new table  
  27.         int j = 1;  
  28.         std::map<unsigned, BattleResultDamageData>::const_iterator map_it = datas[i]->begin(), map_it_end = datas[i]->end();  
  29.         for (; map_it != map_it_end; ++map_it, ++j) {  
  30.             lua_pushinteger(L_, j);  
  31.             newDmgTable(L_, map_it->first, map_it->second);   //atker or defer[id] = dmg_table;  
  32.             lua_settable(L_, -3);  
  33.         }  
  34.     }  
  35.     return 2;  
  36. }  

这下是不是感觉一下子少了好多?这就是代码的重用性!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
详细描述Lua和C之间相互传递Table类型数据 /* ====================================================== */ // 遍历Lua传入Table类型参数, 获取它的Key/Value, 其关键操作是 lua_next() // lua_next() 返回1表示读取成功,返回0表示已经没有数据可读了 // lua_next() 会使用栈顶元素作为Key去定位本次需要取出Table里面的那个值对 // 如果Key=nil, 那就表示本次取出的是第一个元素 // 它会先将当前的这个Key弹出,然后将本次取出的Key/Value压入栈, Value在栈顶 // 一个比较隐晦的处理就是, 我们不应直接使用lua_tostring(L, -2)来读取Key // 因为lua_tostring()在Key类型不是字符串时, 它会修改栈上的Key数据 // 这样, 下次调用lua_next()时, 就会因为Key被修改了而导致错误 // 为此,先调用lua_pushvalue(L, -2),将它Copy一份到栈顶,对这个Copy进行lua_tostring() // 读取Key,Value到C变量里面后,将Value和Copy弹出,留着Key在栈顶,给下次lua_next()用 // // 指令及栈图变化如下: (假如Table的栈下标是Index) // 0. 刚进入函数时 ...Table, ... <--- 这里栈顶 // 1. lua_pushnil(L) ...Table, ..., nil <--- 这里栈顶 // 2. lua_next(L, Index) ...Table, ..., Key, Value <--- 这里栈顶 // 3. lua_pushvalue(L, -2) ...Table, ..., Key, Value, KeyCopy <--- 这里栈顶 // 4. lua_pop(L, 2), ...Table, ..., Key <--- 这里栈顶 // ... 如此重复2,3,4 // N. lua_next(L, Index)返回0 ...Table, ... <--- 这里栈顶 /* ====================================================== */

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值