第一次写。希望表达能够清楚。
用Lua里的table可以实现C++中的数组。Lua的作用一般是用来配置。我把配置的东西写在lua的table里。现在我想要在C++中调用lua中的table,从而把数据传到C++的数组中。
先搞一个一维的table。我是看了《lua程序设计第二版》的25.2节。貌似没有API直接能够取直接取得table的值。或者我不知道吧。书上是用一个getfield函数实现。也就是可能要根据自己的需要重写它。于是模仿的写一个。作用是取得table[key]的值
- int getfield(lua_State *L,int key)
- {
- int result = 0;
- lua_pushnumber(L,key);
- lua_gettable(L,-2);
- if (!lua_isnumber(L,-1))
- cout<<"error"<<endl;
- result = (int)lua_tonumber(L,-1);
- lua_pop(L,1);
- return result;
- }
虽然代码最终运行成功。但是过程中,各种bug。
在书上找到一个函数
- static void stackDump(lua_State *L);
作用是打印交换栈里的数据。
有了这个函数之后,我们对交换栈里的数据情况,就看得一清二楚了。
//完整代码
- #include <iostream>
- #include <stdio.h>
- using namespace std;
- extern "C"
- {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- };
- lua_State *L;
- static void stackDump(lua_State *L)
- {
- int top = lua_gettop(L);
- for (int i = 1; i <= top; i++)
- {
- int t = lua_type(L,i);
- switch(t)
- {
- case LUA_TSTRING:
- printf("'%s'",lua_tostring(L,i));
- break;
- case LUA_TBOOLEAN:
- printf(lua_toboolean(L,i)?"true":"false");
- break;
- case LUA_TNUMBER:
- printf("%g",lua_tonumber(L,i));
- break;
- default:
- printf("%s",lua_typename(L,t));
- }
- printf(" ");
- }
- printf("\n");
- }
- int getfield(lua_State *L,int key)
- {
- int result = 0;
- lua_pushnumber(L,key);
- cout<<"pushnmber : ";
- stackDump(L);
- cout<<"gettable : ";
- lua_gettable(L,-2);
- stackDump(L);
- if (!lua_isnumber(L,-1))
- cout<<"error"<<endl;
- result = (int)lua_tonumber(L,-1);
- cout<<"lua_tonumber : ";
- stackDump(L);
- lua_pop(L,1);
- cout<<"lua_pop : ";
- stackDump(L);
- return result;
- }
- int main()
- {
- L = lua_open();
- luaL_openlibs(L);
- luaL_dofile(L,"test.lua");
- cout<<"start : ";
- stackDump(L);
- lua_getglobal(L,"a");
- cout<<"getglobal : ";
- stackDump(L);
- for (int i = 1; i <= 3; i++)
- {
- cout<<"result:"<<getfield(L,i)<<endl;
- }
- cout<<endl;
- system("pause");
- lua_close(L);
- return 0;
- }
//test.lua
a = {11,12,13}
截图看下结果。
最右是栈顶。数据变化很清楚。
Getfield函数式假设table已经在栈顶。所以我们在前面必须先用lua_getglobal把table放到栈顶。Pushnumber会把数据压栈。接着gettable会取栈顶的数据,根据给出的table位置,这里是-2,计算出table[栈顶]的数据,把它压栈。Pop则是从栈里退出数据,恢复到一开始的状态。接着搞一个二维的table。这也是我需要配置的目的所在。
//test.lua
t ={ {11,12,13},{21,22,23} ,}
最后的逗号,好像可有可无。Lua脚本语法比C++宽松多了。
首先我们要修改getfield。作用是取得table[key1][key2]的值
- int getfield(lua_State *L,int key1,int key2)
- {
- int result = 0;
- lua_pushnumber(L,key1);
- lua_gettable(L,-2);
- lua_pushnumber(L,key2);
- lua_gettable(L,-2);
- if (!lua_isnumber(L,-1))
- cout<<"error"<<endl;
- result = (int)lua_tonumber(L,-1);
- lua_pop(L,2); //退两个元素
- return result;
- }
关键点是在pop时,退了两个元素。
//完整代码
- #include <iostream>
- #include <stdio.h>
- using namespace std;
- extern "C"
- {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- };
- lua_State *L;
- static void stackDump(lua_State *L)
- {
- int top = lua_gettop(L);
- for (int i = 1; i <= top; i++)
- {
- int t = lua_type(L,i);
- switch(t)
- {
- case LUA_TSTRING:
- printf("'%s'",lua_tostring(L,i));
- break;
- case LUA_TBOOLEAN:
- printf(lua_toboolean(L,i)?"true":"false");
- break;
- case LUA_TNUMBER:
- printf("%g",lua_tonumber(L,i));
- break;
- default:
- printf("%s",lua_typename(L,t));
- }
- printf(" ");
- }
- printf("\n");
- }
- int getfield(lua_State *L,int key1,int key2)
- {
- int result = 0;
- lua_pushnumber(L,key1);
- cout<<"pushnumber : ";
- stackDump(L);
- lua_gettable(L,-2);
- cout<<"gettable : ";
- stackDump(L);
- lua_pushnumber(L,key2);
- cout<<"pushnumber : ";
- stackDump(L);
- lua_gettable(L,-2);
- cout<<"gettable : ";
- stackDump(L);
- if (!lua_isnumber(L,-1))
- cout<<"error"<<endl;
- result = (int)lua_tonumber(L,-1);
- cout<<"tonumber : ";
- stackDump(L);
- lua_pop(L,2);
- cout<<"lua_pop : ";
- stackDump(L);
- return result;
- }
- int main()
- {
- L = lua_open();
- luaL_openlibs(L);
- luaL_dofile(L,"test.lua");
- cout<<"start : ";
- stackDump(L);
- lua_getglobal(L,"t");
- cout<<"getglobal : ";
- stackDump(L);
- for (int i = 1; i <= 2; i++)
- for (int j = 1; j <= 3; j++)
- {
- cout<<"result:"<<getfield(L,i,j)<<endl;
- }
- cout<<endl;
- system("pause");
- lua_close(L);
- return 0;
- }
结果部分截图
这样C++就调用了lua里二维table的数据。
这里table里是number型,如果是其他类型,需要自己重写getfield函数。
请发表评论