用lua配置你的应用程序
lazymonkey
posted @ 2012年5月30日 16:25
in 读书
with tags
programming in lua
, 7053 阅读
lua的一个重要的应用是作为程序配置文件的语言(configuration language)。下面通过一个简单示例来说明其应用。
从一个简单示例开始
假设一个c语言程序要画一个窗口界面,窗口的长和宽可以由用户指定。要实现这个功能还有另外更简单的方法,例如使用环境变量或只包含(key, value)形式的普通文本文件,但是如果使用普通文本文件你还是需要对其进行解析。程序的配置文件如下(conf.lua):
--configuration file --to define window_size width = 200 height = 300
下面的代码演示了如何用lua提供的接口来获得这两个全局变量的值:
#include <stdio.h> #include <lua.h> #include <lauxlib.h> #include <lualib.h> int main(int argc, const char *argv[]) { lua_State *l; l = luaL_newstate(); luaL_openlibs(l); if (luaL_loadfile(l, "./conf.lua") != 0) { fprintf(stderr, "luaL_loadfile err: %s.\n", lua_tostring(l, -1)); lua_close(l); return (-1); } if (lua_pcall(l, 0, 0, 0) != 0) { fprintf(stderr, "lua_pcall err: %s.\n", lua_tostring(l, -1)); lua_close(l); return (-1); } lua_getglobal(l, "width"); if (!lua_isnumber(l, -1)) fprintf(stderr, "'width' should be a number.\n"); else printf("width = %d\n", lua_tointeger(l, -1)); lua_pop(l, 1); lua_getglobal(l, "height"); if (!lua_isnumber(l, -1)) fprintf(stderr, "'height' should be a number.\n"); else printf("height = %d\n", lua_tointeger(l, -1)); lua_pop(l, 1); return 0; }
程序首先通过函数luaL_newstate()
创建一个lua状态,继而用luaL_openlibs()
将函数库添加到状态中;然后使用函数
int luaL_loadfile(lua_State *L, const char *filename);
加载并解析lua文件,完成后使用lua_pcall()
执行配置文件中的语句。函数
void lua_getglobal(lua_State *L, const char *name);
将lua文件中名为name
的全局变量的值放入栈中。如果变量name
不存在,lua会向栈中放入一个nil
值。然后使用lua_isnumber()
判断获取的内容是否是数值,如果是的话就将其转换成c语言对应的类型。对于lua栈,有如下的解释:
lua 解释器使用一个栈接口来与调用代码通信。由c代码将发送到lua代码的数据push到栈上;lua 解释器返回的响应也被push到栈上。如果传递给luaL_loadbuffer()
的代码有错误,则错误消息被push到栈上。栈上的项有类型和值。lua_type()
函数查询一个对象的类型;lua_to<type>()
函数(例如 lua_tostring())产生被强制转换成特定c类型的值。用lua编写的代码总是严格遵从栈模型;但是,c代码则可以探查栈的其余部分,甚至可以在栈中插入值。这种接口虽然简单,但是其功能出奇强大。待执行的代码都被同等对待;首先被 push 到栈上,然后等待lua_pcall()
函数来执行它。
上面这个例子很简单,只是用来说明lua的用法,实现这个功能可以使用其它更简单的方法。但是使用lua作为配置文件还有更强大的地方,例如可以使用注释,还可以根据环境变量来作出不同的选择,就像这样:
--configuration file --to define window_size if getenv("DISPLAY") == ":0.0" then width = 300; height = 300 else width = 200; height = 200 end