lua作为配置文件的读取方法

Wesley13
• 阅读 802

struct PictureCfg

{

   string name;

   float rotation;

};

1,全局配置

-- picture0-cfg.lua

name ="dragon.png"

rotation= 180

// 全局配置的读取

voidLoadPictureCfg(vector& 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("%s\n", 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& 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 - %s\n",lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1)));

lua_pop(L, 1); // 移除 'value' ;保留 'key' 做下一次迭代

}

2,二维表配置的读取

-- picture2-cfg.lua

cfg = {

   {  name="dragon.png" ,rotation=180  } ,

   {  name="dragon.png" ,rotation=0  }

}

// 二维表的读取

voidLoadPictureCfg(vector& 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("%s\n", lua_tostring(L,-1)); // 这里是取value,但value不一定为string类型的

lua_pop(L, 1);

}

lua_pop(L, 1);

}

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这