您的位置:首页 > 编程语言 > Lua

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

2017-11-13 12:42 731 查看
[cpp] view
plain copy

例一是参考别人的:  

[cpp] view
plain copy

//定义函数(返回table)  

int func_return_table(lua_State *L)  

{  

 lua_newtable(L);//创建一个表格,放在栈顶  

 lua_pushstring(L, "mydata");//压入key  

 lua_pushnumber(L,66);//压入value  

 lua_settable(L,-3);//弹出key,value,并设置到table里面去  

  

 lua_pushstring(L, "subdata");//压入key  

 lua_newtable(L);//压入value,也是一个table  

 lua_pushstring(L, "mydata");//压入subtable的key  

 lua_pushnumber(L,53);//value  

 lua_settable(L,-3);//弹出key,value,并设置到subtable  

  

 lua_settable(L,-3);//这时候父table的位置还是-3,弹出key,value(subtable),并设置到table里去  

 lua_pushstring(L, "mydata2");//同上  

 lua_pushnumber(L,77);  

 lua_settable(L,-3);  

 return 1;//堆栈里现在就一个table.其他都被弹掉了。  

}  

输出结构体:

[cpp] view
plain copy

{  

     "mydata" = 66,  

     "mydate2" = 77,  

     "subdata" =   

     {  

          "mydata" = 53  

     }  

}  

这里算是一个嵌套的结构体了。
函数解释:

[cpp] view
plain copy

lua_settable(lua_State* L, int index)  

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

相当于 table[key] = value.

例二:

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

代码:

[cpp] view
plain copy

struct BattleResultDamageData  

{  

    Uint32 nIcon;  

    Uint32 nDamage;  

    Uint16 nPetPos;  

    Uint16 nLv;  

    Uint8  nStar;  

    Uint8  nEvo;  

    Uint8  nCurSkin;  

    Uint8  nStage;  

};  

[cpp] view
plain copy

static int luaGetBattleResultData(lua_State *L_)  

{  

    lua_newtable(L_); //创建一个表,放在栈顶  

    int i = 1; //目的:类似tablename[i].id  

    std::map<unsigned, BattleResultDamageData>::const_iterator map_it;  

    for (map_it = SkillActObj::_BattleAtk.begin(); map_it != SkillActObj::_BattleAtk.end(); ++map_it,++i) //可忽略,目的遍历C++中的数据放在lua的table  

    {  

        lua_pushnumber(L_,i);  

        lua_newtable(L_);  

        lua_pushstring(L_,"id");  

        lua_pushnumber(L_,map_it->first);  

        lua_settable(L_,-3);//弹出key,value,并设置到table里面去  

        lua_pushstring(L_,"dmg");  

        lua_pushnumber(L_,map_it->second.nDamage);  

        lua_settable(L_,-3);  

        lua_pushstring(L_,"icon");  

        lua_pushnumber(L_,map_it->second.nIcon);  

        lua_settable(L_,-3);  

        lua_pushstring(L_,"lv");  

        lua_pushnumber(L_,map_it->second.nLv);  

        lua_settable(L_,-3);  

        lua_pushstring(L_,"star");  

        lua_pushnumber(L_,map_it->second.nStar);  

        lua_settable(L_,-3);  

        lua_pushstring(L_,"evo");  

        lua_pushnumber(L_,map_it->second.nEvo);  

        lua_settable(L_,-3);  

        lua_pushstring(L_,"pos");  

        lua_pushnumber(L_,map_it->second.nPetPos);  

        lua_settable(L_,-3);  

        lua_pushstring(L_,"skin");  

        lua_pushnumber(L_,map_it->second.nCurSkin);  

        lua_settable(L_,-3);  

  

        lua_settable(L_,-3);  

    }  

        return 1;  

}  

在lua代码中的使用:

[cpp] view
plain copy

local buffAtk = _G.getBattleResultData();  

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

[cpp] view
plain copy

<Info>0409-210505 654 Lookup local var buffAtk  

<Info>0409-210505 654 name = buffAtk   type = table    value = 0CB685A0  

<Info>0409-210505 654 name = buffAtk[1]    type = table    value = 06CCEA58  

<Info>0409-210505 670 name = buffAtk[1][dmg]   type = number   value = 89298  

<Info>0409-210505 670 name = buffAtk[1][skin]  type = number   value = 0  

<Info>0409-210505 670 name = buffAtk[1][star]  type = number   value = 6  

<Info>0409-210505 689 name = buffAtk[1][evo]   type = number   value = 10  

<Info>0409-210505 692 name = buffAtk[1][id]    type = number   value = 25165827  

<Info>0409-210505 693 name = buffAtk[1][lv]    type = number   value = 131  

<Info>0409-210505 693 name = buffAtk[1][icon]  type = number   value = 1090  

<Info>0409-210505 693 name = buffAtk[1][pos]   type = number   value = 19  

<Info>0409-210505 693 name = buffAtk[2]    type = table    value = 0CC8C038  

<Info>0409-210505 693 name = buffAtk[2][dmg]   type = number   value = 28726  

<Info>0409-210505 693 name = buffAtk[2][skin]  type = number   value = 0  

<Info>0409-210505 710 name = buffAtk[2][star]  type = number   value = 6  

<Info>0409-210505 711 name = buffAtk[2][evo]   type = number   value = 12  

<Info>0409-210505 711 name = buffAtk[2][id]    type = number   value = 25165828  

<Info>0409-210505 711 name = buffAtk[2][lv]    type = number   value = 90  

<Info>0409-210505 711 name = buffAtk[2][icon]  type = number   value = 1325  

<Info>0409-210505 711 name = buffAtk[2][pos]   type = number   value = 51  

例三:

上例返回一个,这里我想返回两个tableaname
.x

如:一个tablename1
.x 与 另一个 tablename2
.x

[cpp] view
plain copy

static int luaGetBattleResultData(lua_State *L_)  

{  

    lua_newtable(L_); // 建立一个table  

    int i = 1;  

    std::map<unsigned, BattleResultDamageData>::const_iterator map_it;  

    for (map_it = SkillActObj::_BattleAtk.begin(); map_it != SkillActObj::_BattleAtk.end(); ++map_it,++i)  

    {     

        lua_pushnumber(L_,i);  

        lua_newtable(L_);  

        lua_pushstring(L_,"id");  

        lua_pushnumber(L_,map_it->first);  

        lua_settable(L_,-3);//弹出key,value,并设置到table里面去  

        //...  

        lua_pushstring(L_,"skin");  

        lua_pushnumber(L_,map_it->second.nCurSkin);  

        lua_settable(L_,-3);  

  

        lua_settable(L_,-3);  

    }  

  

    lua_newtable(L_); //建立另一个table  

    i = 1;  

    for (map_it = SkillActObj::_BattleDef.begin(); map_it != SkillActObj::_BattleDef.end(); ++map_it,++i)  

    {  

        lua_pushnumber(L_,i);  

        lua_newtable(L_);  

        lua_pushstring(L_,"id");  

        lua_pushnumber(L_,map_it->first);  

        lua_settable(L_,-3);//弹出key,value,并设置到table里面去  

        // ...  

        lua_pushstring(L_,"skin");  

        lua_pushnumber(L_,map_it->second.nCurSkin);  

        lua_settable(L_,-3);  

  

        lua_settable(L_,-3);  

    }  

    return 2; // 返回这两个table  

}  

在lua中调用:

[cpp] view
plain copy

local buffAtk, buffDef= _G.getBattleResultData();  

打印这两个table的信息:

[cpp] view
plain copy

<Info>0409-210505 654 Lookup local var buffAtk  

<Info>0409-210505 654 name = buffAtk   type = table    value = 0CB685A0  

<Info>0409-210505 654 name = buffAtk[1]    type = table    value = 06CCEA58  

<Info>0409-210505 670 name = buffAtk[1][dmg]   type = number   value = 89298  

<Info>0409-210505 670 name = buffAtk[1][skin]  type = number   value = 0  

<Info>0409-210505 670 name = buffAtk[1][star]  type = number   value = 6  

<Info>0409-210505 689 name = buffAtk[1][evo]   type = number   value = 10  

<Info>0409-210505 692 name = buffAtk[1][id]    type = number   value = 25165827  

<Info>0409-210505 693 name = buffAtk[1][lv]    type = number   value = 131  

<Info>0409-210505 693 name = buffAtk[1][icon]  type = number   value = 1090  

<Info>0409-210505 693 name = buffAtk[1][pos]   type = number   value = 19  

<Info>0409-210505 693 name = buffAtk[2]    type = table    value = 0CC8C038  

<Info>0409-210505 693 name = buffAtk[2][dmg]   type = number   value = 28726  

<Info>0409-210505 693 name = buffAtk[2][skin]  type = number   value = 0  

<Info>0409-210505 710 name = buffAtk[2][star]  type = number   value = 6  

<Info>0409-210505 711 name = buffAtk[2][evo]   type = number   value = 12  

<Info>0409-210505 711 name = buffAtk[2][id]    type = number   value = 25165828  

<Info>0409-210505 711 name = buffAtk[2][lv]    type = number   value = 90  

<Info>0409-210505 711 name = buffAtk[2][icon]  type = number   value = 1325  

<Info>0409-210505 711 name = buffAtk[2][pos]   type = number   value = 51  

<Info>0409-210505 711   

[cpp] view
plain copy

<Info>0409-212740 450 Lookup local var buffDef  

<Info>0409-212740 451 name = buffDef   type = table    value = 0CDD1EB8  

<Info>0409-212740 451 name = buffDef[1]    type = table    value = 0CEEFCA8  

<Info>0409-212740 451 name = buffDef[1][dmg]   type = number   value = 1992  

<Info>0409-212740 451 name = buffDef[1][skin]  type = number   value = 0  

<Info>0409-212740 466 name = buffDef[1][star]  type = number   value = 1  

<Info>0409-212740 466 name = buffDef[1][evo]   type = number   value = 4  

<Info>0409-212740 466 name = buffDef[1][id]    type = number   value = 25165829  

<Info>0409-212740 482 name = buffDef[1][lv]    type = number   value = 85  

<Info>0409-212740 482 name = buffDef[1][icon]  type = number   value = 1005  

<Info>0409-212740 482 name = buffDef[1][pos]   type = number   value = 2  

<Info>0409-212740 482 name = buffDef[2]    type = table    value = 0CEED4D0  

<Info>0409-212740 482 name = buffDef[2][dmg]   type = number   value = 2941  

<Info>0409-212740 482 name = buffDef[2][skin]  type = number   value = 0  

<Info>0409-212740 499 name = buffDef[2][star]  type = number   value = 2  

<Info>0409-212740 499 name = buffDef[2][evo]   type = number   value = 6  

<Info>0409-212740 499 name = buffDef[2][id]    type = number   value = 25165830  

<Info>0409-212740 499 name = buffDef[2][lv]    type = number   value = 85  

<Info>0409-212740 499 name = buffDef[2][icon]  type = number   value = 1075  

<Info>0409-212740 499 name = buffDef[2][pos]   type = number   value = 16  

<Info>0409-212740 499 name = buffDef[3]    type = table    value = 0D0E83A0  

<Info>0409-212740 516 name = buffDef[3][dmg]   type = number   value = 308  

<Info>0409-212740 519 name = buffDef[3][skin]  type = number   value = 1  

<Info>0409-212740 521 name = buffDef[3][star]  type = number   value = 0  

<Info>0409-212740 523 name = buffDef[3][evo]   type = number   value = 6  

<Info>0409-212740 523 name = buffDef[3][id]    type = number   value = 25165831  

<Info>0409-212740 523 name = buffDef[3][lv]    type = number   value = 85  

<Info>0409-212740 523 name = buffDef[3][icon]  type = number   value = 1080  

<Info>0409-212740 523 name = buffDef[3][pos]   type = number   value = 17  

<Info>0409-212740 523 name = buffDef[4]    type = table    value = 0CD85A00  

<Info>0409-212740 523 name = buffDef[4][dmg]   type = number   value = 792  

<Info>0409-212740 539 name = buffDef[4][skin]  type = number   value = 0  

<Info>0409-212740 539 name = buffDef[4][star]  type = number   value = 0  

<Info>0409-212740 539 name = buffDef[4][evo]   type = number   value = 0  

<Info>0409-212740 539 name = buffDef[4][id]    type = number   value = 25165832  

<Info>0409-212740 539 name = buffDef[4][lv]    type = number   value = 85  

<Info>0409-212740 539 name = buffDef[4][icon]  type = number   value = 1145  

<Info>0409-212740 539 name = buffDef[4][pos]   type = number   value = 30  

<Info>0409-212740 554 name = buffDef[5]    type = table    value = 0C7CF7F8  

<Info>0409-212740 554 name = buffDef[5][dmg]   type = number   value = 1608  

<Info>0409-212740 554 name = buffDef[5][skin]  type = number   value = 0  

<Info>0409-212740 554 name = buffDef[5][star]  type = number   value = 2  

<Info>0409-212740 554 name = buffDef[5][evo]   type = number   value = 4  

<Info>0409-212740 554 name = buffDef[5][id]    type = number   value = 25165833  

<Info>0409-212740 571 name = buffDef[5][lv]    type = number   value = 47  

<Info>0409-212740 574 name = buffDef[5][icon]  type = number   value = 1090  

<Info>0409-212740 577 name = buffDef[5][pos]   type = number   value = 19  

<Info>0409-212740 578   

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

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

[cpp] view
plain copy

static void setTableInt(lua_State *L_, const char *sKey, lua_Number nVal)  

{  

    lua_pushstring(L_, sKey);  

    lua_pushnumber(L_, nVal);  

    lua_settable(L_,-3);  

}  

  

static void newDmgTable(lua_State *L_, unsigned nEntityId, const BattleResultDamageData &data)  

{  

    lua_newtable(L_);  

    setTableInt(L_, "id", nEntityId);  

    setTableInt(L_, "dmg", data.nDamage);  

    setTableInt(L_, "icon", data.nIcon);  

    setTableInt(L_, "lv", data.nLv);  

    setTableInt(L_, "star", data.nStar);  

    setTableInt(L_, "evo", data.nEvo);  

    setTableInt(L_, "pos", data.nPetPos);  

    setTableInt(L_, "skin", data.nCurSkin);  

}  

  

static int luaGetBattleResultData(lua_State *L_)  

{  

    std::map<unsigned, BattleResultDamageData> *datas[] = {&SkillActObj::_BattleAtk, &SkillActObj::_BattleDef};  

    for (unsigned i = 0; i < 2; ++i)   

    {  

        lua_newtable(L_);   //new table  

        int j = 1;  

        std::map<unsigned, BattleResultDamageData>::const_iterator map_it = datas[i]->begin(), map_it_end = datas[i]->end();  

        for (; map_it != map_it_end; ++map_it, ++j) {  

            lua_pushinteger(L_, j);  

            newDmgTable(L_, map_it->first, map_it->second);   //atker or defer[id] = dmg_table;  

            lua_settable(L_, -3);  

        }  

    }  

    return 2;  

}  

这下是不是感觉一下子少了好多?这就是代码的重用性!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: