遇到的错误使用的例子
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
???
新建一个lua_State 结构的指针,用以记录栈的状态
打开所有的lua标准库
加载并运行lua程序文件
lua_pcall(L,0,0,0)调用时,检测栈顶是否有存在错误
销毁对象
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;
}
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)
}
lua和C之间的数据交换是通过一个虚拟栈实现的,这个栈严格遵守先进后出的原则;可以用 1 ~ N 从栈底向上索引,也可以用 -1 ~ -N 从栈顶向下索引,一般后者更加常用,C通过压栈一个元素,或者弹栈一个元素,获取自己想要的数据。
手册中的描述
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
void lua_pushnil (lua_State *L);
Pushes a nil value onto the stack.
向栈中压入一个空值
手册中的描述
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压入栈中。
简单来说就是,弹栈,压栈压栈。
void lua_pop (lua_State *L, int n);
Pops n elements from the stack.
从栈中弹出n个元素
根据注释(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函数的使用