前面介紹了當lua
文件做配置使用時,該如何使用 API 接口去獲取配置文件信息, lua 文件作為配置文件使用還是比較方便的,解析程序也比較容易編寫,但是前文只介紹了如何 k-v
類型的配置,意味著 k 不能相同既绕。所以本文介紹更高級的使用方式,本人將介紹如何利用lua中的數(shù)據(jù)結(jié)構(gòu)table
來作為配置文件,并在最后介紹 C 如何調(diào)用 lua 中的函數(shù)啄刹。
前言
table
作為 lua 語言中的一種數(shù)據(jù)結(jié)構(gòu),相對于 C/C++ 語言而言,簡直就是 bug 一般的存在,使用真是太方便了,其組合簡單易用,可以任意組合成不同的類型 table。本文就介紹如何操作 table 的 API,并示例使用table作為配置數(shù)據(jù)凄贩。
API
下面介紹操作 table
的AP
獲取table元素
int lua_getfield (lua_State *L, int index, const char *k);
作用:把 t[k] 的值壓棧,這里的 t 是索引指向的值
設(shè)置table元素
void lua_setfield (lua_State *L, int index, const char *k);
作用:做一個等價于 t[k] = v 的操作,這里 t 是給出的索引處的值誓军, 而 v 是棧頂?shù)哪莻€值
下面介紹其他相關(guān)的函數(shù)
判斷棧中值得類型
int lua_istable (lua_State *L, int index);
作用:當給定索引的值是一張表時,返回 1 ,否則返回 0 。
int lua_isfunction (lua_State *L, int index);
作用:當給定索引的值是一個函數(shù)( C 或 Lua 函數(shù)均可)時,返回 1 ,否則返回 0 疲扎。
將指定索引值轉(zhuǎn)換成字符串
int lua_isfunction (lua_State *L, int index);
作用:當給定索引的值是一個函數(shù)( C 或 Lua 函數(shù)均可)時昵时,返回 1 捷雕,否則返回 0 。
示例
/*
* gcc test.c -llua -lm -ldl
*/
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <stdio.h>
/*
* 從棧底到棧頂依次遍歷整個堆棧
*/
static void stackDump(lua_State* L)
{
int i;
int top = lua_gettop(L);
for(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));
break;
}
printf(" ");
}
printf("\n");
}
void PrintfLuaType(lua_State* L, int type)
{
printf("'%s'", lua_typename(L, type));
}
int main(int argc, char *argv[])
{
lua_State *L = lua_open();
luaL_openlibs(L);
//加載配置文件
int iRet = luaL_loadfile(L, "config.lua");
if(iRet)
{
printf("laodfile config.lua fail!!\n");
lua_close(L);
return 0;
}
iRet = lua_pcall(L, 0, 0, 0);
if(iRet)
{
printf("lua_pcall fail!!\n");
lua_close(L);
return 0;
}
lua_getglobal(L, "color");
stackDump(L);
if(!lua_istable(L, -1))
{
printf("It's not table\n");
lua_close(L);
return 0;
}
//讀取table中字段的值,將值壓入棧,因此下一個獲取值時,table的index已經(jīng)改變了
lua_getfield(L, -1, "r");
lua_getfield(L, -2, "g");
lua_getfield(L, -3, "b");
stackDump(L);
if(!lua_isnumber(L, -3))
{
printf("r is not number\n");
lua_close(L);
return 0;
}
if(!lua_isnumber(L, -2))
{
printf("g is not number\n");
lua_close(L);
return 0;
}
if(!lua_isnumber(L, -1))
{
printf("b is not number\n");
lua_close(L);
return 0;
}
int r = lua_tointeger(L, -3);
int g = lua_tointeger(L, -2);
int b = lua_tointeger(L, -1);
printf("r[%d] g[%d] b[%d]\n", r, g, b);
//調(diào)用函數(shù)
lua_getglobal(L, "add");
if(!lua_isfunction(L, -1))
{
printf("It's not function\n");
lua_close(L);
return 0;
}
//壓入?yún)?shù)
lua_pushnumber(L, 10); //第一個參數(shù)
lua_pushnumber(L, 20); //第二個參數(shù)
iRet = lua_pcall(L, 2, 1, 0);
if(iRet)
{
printf("%s\n", lua_tostring(L, -1));
lua_close(L);
return 0;
}
if(!lua_isnumber(L, -1))
{
printf("Result is not number\n");
lua_close(L);
return 0;
}
iRet = lua_tonumber(L, -1);
printf("Ret[%d]\n", iRet);
lua_close(L);
return 0;
}
lua文件為:
color = {r=128, g=123, b=255}
function add(iA, iB)
return iA + iB
end
編譯執(zhí)行后結(jié)果為:
'table'
'table' '128' '123' '255'
r[128] g[123] b[255]
Ret[30]
總結(jié)
lua中table的操作,本文只是介紹簡單的結(jié)構(gòu),table可以互相嵌套組成比較復(fù)雜的結(jié)構(gòu),操作的時候也需要相當?shù)淖⒁庖忌τ贏PI的細節(jié)不料及的可以查閱手冊,如何設(shè)置table中的值,本文只給出了API介紹,并未給出示例,有興趣的可以自己去嘗試下救巷。多多寫寫代碼總歸是好的,看得過癮不如自己找個bug解決來得爽。