lua作为配置文件的读取方法
struct PictureCfg { ???string name; ???float rotation; }; 1,全局配置 -- picture0-cfg.lua name ="dragon.png" rotation= 180 // 全局配置的读取 voidLoadPictureCfg(vector<PictureCfg>& rstPictureCfgVec) { ???PictureCfg stCfg; ? ???lua_State* L = luaL_newstate(); // 创建的一个新的独立的状态机 ???luaL_dofile(L,"picture0-cfg.lua"); ? ???lua_getglobal(L,"name"); // 把全局变量 name 里的值压入堆栈,等价于lua_getfield(L,LUA_GLOBALSINDEX,"name") ???printf("%sn",lua_typename(L,lua_type(L,-1))); ???assert(lua_isstring(L,-1) == 1); // 当给定索引的值是一个字符串或是一个数字(数字总能转换成字符串)时,返回 1 ,否则返回 0 ???stCfg.name = lua_tostring(L,-1); // 把给定索引处的 Lua 值转换为一个 C 字符串,注意该系列的函数不会将值从栈上弹出的 ? ???lua_getglobal(L,"rotation"); // ???assert(lua_isnumber(L,-1) == 1); ???stCfg.rotation = (float) lua_tonumber(L,-1); // 把给定索引处的 Lua 值转换为lua_Number 这样一个 C 类型(参见 lua_Number )。这个 Lua 值必须是一个数字或是一个可转换为数字的字符串(参见§2.2.1 );否则,lua_tonumber 返回 0 。typedef double lua_Number; ? ???rstPictureCfgVec.push_back(stCfg); ? ???lua_close(L); } 2,一维表配置的读取 -- picture1-cfg.lua cfg = { name="dragon.png",rotation=180 } // 一维表的读取 voidLoadPictureCfg(vector<PictureCfg>& rstPictureCfgVec) { ???lua_State* L = luaL_newstate(); ???luaL_dofile(L,"picture1-cfg.lua"); ? ???// get the table ???lua_getglobal(L,"cfg" ); // 将全局变量cfg压栈,cfg是table类型的,一维表 ???assert(lua_istable(L,-1) == 1); ? ???PictureCfg stCfg; ? ???// push the key to stack for getting the value ???lua_pushstring(L,"name"); // ???// now the table is in the -2 and key in the top(-1) ???lua_gettable(L,-2); ???/* ???void lua_gettable (lua_State *L,int index); ??? 把 t[k] 值压入堆栈,这里的 t 是指有效索引 index 指向的值,而 k 则是栈顶放的值。 ??? 这个函数会弹出堆栈上的key (把结果放在栈上相同位置)。 ???*/ ???assert(lua_isstring(L,-1 )); ???stCfg.name = lua_tostring(L,-1 ); ???lua_pop(L,1 ); ? ???// push the key to stack for getting the value ???lua_pushstring(L,"rotation"); ???// now the table is in the -2 and key in the top(-1) ???lua_gettable(L,-2 ); ???assert(lua_isnumber(L,-1)); ???stCfg.rotation = lua_tonumber(L,-1); ? ???rstPictureCfgVec.push_back(stCfg); ? ???/* 清空栈 */ ???lua_pop(L,2); ? ???lua_close(L); } 典型的一维表遍历方法是这样的: int t_idx = lua_gettop(L);? // 取 table 索引值 lua_pushnil(L);? // 第一个 key while (lua_next(L,t_idx) != 0) { // 现在栈顶(-1)是 value,-2 位置是对应的 key // 这里可以判断 key 是什么并且对 value 进行各种处理 printf("%s - %sn",-2)),-1))); lua_pop(L,1); // 移除 'value' ;保留 'key' 做下一次迭代 } 2,二维表配置的读取 -- picture2-cfg.lua cfg = { ???{? name="dragon.png",rotation=180? }, ???{? name="dragon.png",rotation=0? } } // 二维表的读取 voidLoadPictureCfg(vector<PictureCfg>& rstPictureCfgVec) { ???lua_State* L = luaL_newstate(); ???luaL_dofile(L,"picture2-cfg.lua"); ? ???// get the table ???lua_getglobal(L,"cfg"); // 将全局变量cfg压栈,cfg是table类型的,且是二维表 ???assert(lua_istable(L,-1) == 1); ???/* ???int lua_type (lua_State *L,int index); ??? 返回给定索引处的值的类型,当索引无效时则返回 LUA_TNONE (那是指一个指向堆栈上的空位置的索引)。 lua_type 返回的类型是一些个在 lua.h 中定义的常量: LUA_TNIL , LUA_TNUMBER , LUA_TBOOLEAN , LUA_TSTRING , LUA_TTABLE , LUA_TFUNCTION , LUA_TUSERDATA , LUA_TTHREAD , LUA_TLIGHTUSERDATA 。 ???const char *lua_typename? (lua_State*L,int tp); ??? 返回 tp 表示的类型名,这个 tp 必须是 lua_type 可能返回的值中之一。 ???*/ ? ???lua_pushnil(L); /* first key */ // 把一个 nil 压栈作为遍历table的第一个key ???while (lua_next(L,-2) != 0) // index -2 is the table ??? { ???????/* ???????int lua_next (lua_State *L,int index); ???????从栈上弹出一个 key(键),然后把index指定的表中的下一个key-value(健值)对压入堆栈 ???????如果表中已无更多元素,那么 lua_next 将返回 0 (什么也不压入堆栈)。 ???????*/ ???????/* 'key' (at index -2) and 'value' (at index -1) */ ???????PictureCfg rstCfg; ? ???????// push the key to stack for getting the value ???????lua_pushstring(L,"name"); // ???????/* ???????void lua_pushstring (lua_State *L,const char *s); ???????把指针 s 指向的以零结尾的字符串压栈。 Lua 对这个字符串做一次内存拷贝(或是复用一个拷贝),因此 s 处的内存在函数返回后,可以释放掉或是重用于其它用途。字符串中不能包含有零字符;第一个碰到的零字符会认为是字符串的结束。 ???????*/ ???????// now the table is in the -2 and key in the top(-1) ???????lua_gettable(L,-2); ???????/* ???????void lua_gettable (lua_State *L,int index); ???????把 t[k] 值压入堆栈,这里的 t 是指有效索引 index 指向的值,而 k 则是栈顶放的值。 ???????这个函数会弹出堆栈上的 key (把结果放在栈上相同位置)。 ???????*/ ???????assert(lua_isstring(L,-1)); // 第一个子表的name的值现在位于栈顶 ???????rstCfg.name = lua_tostring(L,-1); ???????lua_pop(L,1); ???????/* ???????void lua_pop (lua_State *L,int n); ???????从堆栈中弹出 n 个元素。 ??? ????*/ ? ???????// push the key to stack for getting the value ???????lua_pushstring(L,"rotation"); ???????// now the table is in the -2 and key in the top(-1) ???????lua_gettable(L,-2); ???????assert(lua_isnumber(L,-1)); ???????rstCfg.rotation = lua_tonumber(L,-1); ? ???????rstPictureCfgVec.push_back(rstCfg); ? ???????/* removes the key we pushed and the 'value' of the global table ;?? keeps 'key' for next iteration */ ???????lua_pop(L,2); ??? } ? ???lua_close(L); } 另一种遍历二维表的方式如下: t_idx = lua_gettop(L); lua_pushnil(L); while (lua_next(L,t_idx)) { it_idx = lua_gettop(L); // inner table lua_pushnil(L); while(lua_next(L,it_idx)) { printf("%sn",lua_tostring(L,-1)); // 这里是取value,但value不一定为string类型的 lua_pop(L,1); } lua_pop(L,1); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |