C中的lua二维表遍历
来源:互联网 发布:冰川网络远征ol珍宝阁 编辑:程序博客网 时间:2024/05/22 06:28
C中的lua二维表遍历
一、 主要内容
- lua中二维表的表示
- C API 的使用
- 打开lua
- 关闭lua
- main
- C中的遍历函数
- lua和C中的虚拟栈
- 运行结果
遇到的错误使用的例子
二、lua中的二维表表示
lua代码
01.#! /usr/bin/lua 02. 03.cmdlist= 04.{ 05. { 06. send="w 0x0000 0x0001", 07. plain="???", 08. dalay=2 --[[ms]] 09. }, 10. 11. { 12. send="w 0x0000 0x0002", 13. plain="???", 14. dalay=2 --[[ms]] 15. }, 16. 17. { 18. send="w 0x0000 0x0003", 19. plain="???", 20. dalay=2 --[[ms]] 21. }, 22. 23. { 24. send="w 0x0000 0x0004", 25. plain="???", 26. dalay=2 --[[ms]] 27. }, 28. 29.} 30. 31. 32.--[[ 33. 34.for k=1,#cmdlist do 35. print(cmdlist[k].send) 36. print(cmdlist[k].plain) 37. print(cmdlist[k].dalay) 38. 39.end 40. 41.--]]
lua运行结果
w 0x0000 0x0001 2 ??? w 0x0000 0x0002 2 ??? w 0x0000 0x0003 2 ??? w 0x0000 0x0004 2 ???
三、C API的使用
lua_State * luaL_newstate(void)
新建一个lua_State 结构的指针,用以记录栈的状态
luaL_openlibs(lua_State * L)
打开所有的lua标准库
luaL_loadfile(lua_State * L,char* filepath)
加载并运行lua程序文件
int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
lua_pcall(L,0,0,0)调用时,检测栈顶是否有存在错误
lua_close
销毁对象
main函数实现
int main( int argc,char** argv) { int error; char buff[256]; char *filename = argv[1]; lua_State *L =luaL_newstate();; luaL_openlibs(L); //加载运行,检测是否有错误 if(luaL_loadfile(L,filename) || lua_pcall(L,0,0,0)) { luaL_error(L,"loadfile error! %s \n",lua_tostring(L,-1)); } //遍历函数,下面会写他的实现 get_table(L ,"cmdlist"); lua_close(L); return 0; }
四、C中的遍历函数
1、void get_table(lua_State * L ,char * tabname)
void get_table(lua_State * L ,char * tabname) { int it_idx=0; printf("二维表的遍历\n"); lua_getglobal(L,tabname); //(1) it_idx = lua_gettop(L); printf("t_id=%d\n",it_idx); lua_pushnil(L); //(2) while (lua_next(L, -2)) //stack -2 == tabname //(3) { printf("============================\n"); lua_pushnil(L); //(4) while(lua_next(L, -2)) //(5) { printf("%s\n", lua_tostring(L, -1)); lua_pop(L, 1); //(6) } lua_pop(L, 1); //(7) } lua_pop(L,1); //(8) }
2、 虚拟栈
lua和C之间的数据交换是通过一个虚拟栈实现的,这个栈严格遵守先进后出的原则;可以用 1 ~ N 从栈底向上索引,也可以用 -1 ~ -N 从栈顶向下索引,一般后者更加常用,C通过压栈一个元素,或者弹栈一个元素,获取自己想要的数据。
3.遍历中使用到的函数
lua_getglobal
手册中的描述
lua_getglobal int lua_getglobal (lua_State *L, const char *name);
Pushes onto the stack the value of the global name. Returns the type
of that value.
向栈中压入一个name对应的lua中的元素,返回这个元素的类型
lua_pushnil
手册中的描述
lua_pushnil
void lua_pushnil (lua_State *L);
Pushes a nil value onto the stack.
向栈中压入一个空值
lua_next
手册中的描述
lua_next
int lua_next (lua_State *L, int index); Pops a key from the stack, and
pushes a key–value pair from the table at the given index (the “next”
pair after the given key). If there are no more elements in the table,
then lua_next returns 0 (and pushes nothing).A typical traversal looks like this:
/* table is in the stack at index 't' */ lua_pushnil(L); /* first key */ while (lua_next(L, t) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) */ printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); /* removes 'value'; keeps 'key' for next iteration */ lua_pop(L, 1); } While traversing a table, do not call lua_tolstring directly on a key, unless you know that the key is actually a string. Recall that
lua_tolstring may change the value at the given index; this confuses
the next call to lua_next.See function next for the caveats of modifying the table during its
traversal.
这个函数以参数index指向的栈中的元素为对象,以栈顶元素的下一个为索引,先将栈顶弹出,再讲index指向的元素的key和value压入栈中。
简单来说就是,弹栈,压栈压栈。
lua_pop
void lua_pop (lua_State *L, int n);
Pops n elements from the stack.
从栈中弹出n个元素
4.执行过程
根据注释(1)(2)(3)(4)(5)(6)(7)…
(1):表名压栈
顶 栈: 表名
(2):压入一个空元素,等next函数检测到这个空后,会自动的将表的第一个元素加载到栈中
顶(-1) (-2) 栈: 空(nil),表名
(3): 以栈中-2处的元素为表名,将空弹出,获取表名的key和value,依次压栈
顶 栈: value,key,表名
注意 :由于是二维表,此时的value是一个表
结构如下
[1]= { send="w 0x0000 0x0001", plain="???", dalay=2 --[[ms]] },
(4):作用同2
顶 栈: 空(nil),value,key,表名
(5)以栈中-2处的元素为表名,将空弹出,获取表名的key和value,依次压栈
注意:此时的-2处的元素,是表的一维的值,也就是
[1]= { send="w 0x0000 0x0001", plain="???", dalay=2 --[[ms]] },
所以这个执行完成后的栈的样子是
顶 栈:w 0x0000 0x0001 ,send,value,key,表名
(6)从栈顶弹出一个元素;
顶 栈:send,value,key,表名
下一次的next会弹出send,压入send之后的key和value,当没有可用的key,栈中为
顶 栈:value,key,表名
(7)同上,一个内层循环结束,这句执行完成后的栈是:
顶 栈:key,表名
准备取key的下一个值,如果没有下一个了
顶 栈:表名
(8)将表名弹出,此时的栈为空
五、运行结果
./test config.lua 二维表的遍历 t_id=1 ============================ w 0x0000 0x0001 2 ??? ============================ w 0x0000 0x0002 2 ??? ============================ w 0x0000 0x0003 2 ??? ============================ w 0x0000 0x0004 2 ???
六、网上遇到的错误例子
七、结束语
刚刚开始接触lua,如果有哪里说的不对或者不完善,欢迎指出。网上的错误例子是促使我写这个笔记的原因,太坑了,我不确定是不是别人用错了或者是版本不一致导致的,了解的同学有知道的可以分享下,我使用的版本是v5.3.4。
第一次使用markdown,感觉不错。
ps:例子改天再加主要是lua_next函数的使用
- C中的lua二维表遍历
- 如何用C API遍历Lua脚本中的表
- C/C++遍历Lua中的table
- C++遍历Lua二维table
- c中遍历lua表结构
- c中遍历lua表结构
- c中遍历lua表结构
- lua中的table遍历
- PHP中的二维数组遍历
- C遍历lua的table
- C遍历LUA表和调用LUA函数的简单Demo
- java中的遍历及二维数组
- C语言编程-指针遍历二维数组
- C语言 使用指针遍历二维数组
- lua中的4 种常用遍历
- 【转载】Lua中的四种遍历方式
- Lua 学习笔记:C API 遍历 Table
- Lua 学习笔记:C API 遍历 Table
- 作为开发人员应该了解到的一些开发工具的快捷键
- 使用webpack 构建handlebars+jquery+bootstrap的开发环境
- StringBuffer类
- 初涉MySql性能优化
- 堆栈的顺序存储---顺序栈
- C中的lua二维表遍历
- JAVA-比较器
- Intel(R) Ethernet connection (2) I219-LM 设置抓取VLAN tag报文
- Java的oauth2.0 服务端与客户端的实现
- JAVA-Exception异常
- leetcode Plus One 加一
- 祖国生日之际,发生了一件大事!
- ubuntu14.04安装nexus
- JAVA-垃圾回收