引用http://blog.csdn.net/yanjun_1982/article/details/7596171
今天上班的时候和程序对一个功能的程序接口,需求是这样的:脚本代码根据配置文件生成一组中奖信息,用table来保存,然后将这个table传给程序接口,程序根据这个table中的数据向玩家显示中奖界面。很简单的一个功能,脚本这边的函数很快就写完了,然后我就琢磨着程序的接口应该怎么写,由于之前没有试过在程序接口中访问lua脚本传过来的table,所以遇到了一些麻烦,上网搜了一下相关资料,总算搞清楚了。现在就简单总结一下c/c++与lua交互中关于table的一些用法吧。
有个Lua脚本函数叫OpenAwardWindow,它是c++实现的一个接口,对应的c++函数为LuaOpenAwardWindow,它的输入参数是一个table。现在我们要解决的问题是怎么在LuaOpenAwardWindow中遍历table中的所有元素。我们知道lua是通过栈来实现和c语言的交互的,至于为什么是栈呢,以后再专门说明吧。脚本传过来的table是放在栈顶的,即栈的-1位置,我们可以用lua_istable(L, -1)来检查输入参数是否合法。lua的数据类型和c的数据类型是不一样的,它们必须用专门的函数的转换,比如lua_tonumber(L, -1)就是把栈顶的数据转为double类型,lua_tostring(L, -1)是转为带结束符的字符串类型。新手一定会说,那lua_totable(L, -1)就是转换了table类型咯^_^。如果c有table这种数据类型,那一定会有这个函数的,可惜c没有。不过在这里我有个想法,能不能用c实现一种类型,它是可以和lua的table对应的呢?这样就真的可以有lua_totable这个接口了,这样c访问table就方便多了。我们还是回到如何在c中遍历table的问题中吧。在c中,它是这样访问table中的一个元素的:
//将一个key放到栈顶,这个key为1。如果你的key是字符串,那就用lua_pushstring。
lua_pushnumber(L, 1);
//table一开始是在栈顶,即-1处的,但上面的语句压入了一个值,栈顶变-2了。
//lua_gettable的作用就是以栈顶的值作为key来访问-2位置上的table。
lua_gettable(L, -2);
这时table中的第1个元素的值就放到栈顶了,你想怎么使用就怎么使用吧。
上面说的是访问table中的一个元素的方法,那要怎么样遍历table中的所有元素呢?如果table是一个以连续的整形作为key的table, 可以用下面方法:
- int size = lua_objlen(L,-1);//相关于#table
- for(int i = 1; i <= size; i++)
- {
- lua_pushnumber(L, i);
- lua_gettable(L, -2);
- //这时table[i]的值在栈顶了
- lua_pop(L, 1);//把栈顶的值移出栈,保证栈顶是table以便遍历。
- };
如果table中的key是任意值呢?可以用下面的方法:
- lua_pushnill(L);
- while(lua_next(L, -2))
- {
- //这时值在-1(栈顶)处,key在-2处。
- lua_pop(L, 1);//把栈顶的值移出栈,让key成为栈顶以便继续遍历
- }
这里重点说明一下lua_next。它执行操作是这样的,先判断上一个key的值(这个值放在栈顶,如果是nil,则表示当前取出的是table中第一个元素的值),然后算出当前的key,这时先把栈顶出栈,将新key进栈,最后将新key对应的值进栈。这样栈顶就是table中第一个遍历到的元素的值。用完这个值后,我们要把这个值出栈,让key在栈顶以便继续遍历。当根据上一个key值算不出下一个key值时,lua_next返回0,结束循环。
今天学习了两种遍历c代码中遍历tabl的方法,让我对lua的认识又深入了许多,由于之前太懒,而且对lua源码中“乱78糟“