Lua C接口API 4

前面介紹了當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解決來得爽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末句柠,一起剝皮案震驚了整個濱河市浦译,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溯职,老刑警劉巖囤捻,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件醒第,死亡現(xiàn)場離奇詭異羽嫡,居然都是意外死亡芦鳍,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門僻族,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粘驰,“玉大人,你說我怎么就攤上這事述么◎蚴” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵碉输,是天一觀的道長籽前。 經(jīng)常有香客問我,道長敷钾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任肄梨,我火速辦了婚禮阻荒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘众羡。我一直安慰自己侨赡,他們只是感情好,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布粱侣。 她就那樣靜靜地躺著羊壹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪齐婴。 梳的紋絲不亂的頭發(fā)上油猫,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天,我揣著相機與錄音柠偶,去河邊找鬼情妖。 笑死睬关,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的毡证。 我是一名探鬼主播电爹,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼料睛!你這毒婦竟也來了丐箩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤恤煞,失蹤者是張志新(化名)和其女友劉穎雏蛮,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阱州,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡挑秉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苔货。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犀概。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖夜惭,靈堂內(nèi)的尸體忽然破棺而出姻灶,到底是詐尸還是另有隱情,我是刑警寧澤诈茧,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布产喉,位于F島的核電站,受9級特大地震影響敢会,放射性物質(zhì)發(fā)生泄漏曾沈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一鸥昏、第九天 我趴在偏房一處隱蔽的房頂上張望塞俱。 院中可真熱鬧,春花似錦吏垮、人聲如沸障涯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唯蝶。三九已至,卻和暖如春遗嗽,著一層夾襖步出監(jiān)牢的瞬間粘我,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工媳谁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留涂滴,地道東北人友酱。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像柔纵,于是被迫代替她去往敵國和親缔杉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359

推薦閱讀更多精彩內(nèi)容