美文网首页
Lua C接口API 3

Lua C接口API 3

作者: 小小小码农 | 来源:发表于2016-12-06 20:45 被阅读64次

    Lua C 接口 API 接口比较多,主要都是围绕交互栈的操作,前面学习了如何简单操作交互栈,且相应的API比较多,看起来比较麻烦,也没撒实际用处,所以决定换一种方式来学习,决定通过解决实际的问题来了解这些API。


    前言

    经常写代码的人应该会遇到要使用配置文件的问题,目前比较流行的配置文件方式有inixmljsonyaml之类的,每一种配置文件的方式都有一种特有的数据结构和解析方式,然而呢,lua其实也可以用来做配置文件,且解析也相应比较简单。

    API

    下面介绍读取lua配置文件相关的API

    载入配置文件

    int luaL_loadfile (lua_State *L, const char *filename);
    

    作用:把一个文件加载为 Lua 代码块,代码块的名字被命名为 filename。如果 filename 为NULL,它从标准输入加载。如果文件第一行以#开头,则忽略这一行。

    返回值:

    • LUA_OK: 没有错误。
    • LUA_ERRSYNTAX: 在预编译时碰到语法错误。
    • LUA_ERRMEM: 内存分配错误。
    • LUA_ERRGCMM: 在运行 __gc 元方法时出错了。 (这个错误和代码块加载过程无关,它是由垃圾收集器引发的。)

    执行lua代码块

    int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
    

    作用: nargs 为压入栈的参数个数, 函数被调用完后所有参数都会出栈。而函数返回值此时入栈,返回值个数调整为nresults。如果 msgh 是 0,返回在栈顶的错误消息就和原始错误消息完全一致。 否则,msgh 就被当成是错误处理函数在栈上的索引位置。

    返回值:

    • LUA_OK (0): 成功。
    • LUA_ERRRUN: 运行时错误。
    • LUA_ERRMEM: 内存分配错误。对于这种错,Lua 不会调用错误处理函数。
    • LUA_ERRERR: 在运行错误处理函数时发生的错误。
    • LUA_ERRGCMM: 在运行 __gc 元方法时发生的错误。 (这个错误和被调用的函数无关。)

    获取变量

    int lua_getglobal (lua_State *L, const char *name);
    

    作用:把全局变量 name 里的值压栈,返回该值的类型。

    判断数据类型

    int lua_isnumber (lua_State *L, int index);
    

    作用:当给定索引的值是一个数字,或是一个可转换为数字的字符串时,返回 1 ,否则返回 0 。

    获取数据

    lua_Integer lua_tointeger (lua_State *L, int index);
    

    作用: * 将给定索引处的 Lua 值转换为带符号的整数类型 lua_Integer。 这个 Lua 值必须是一个整数,或是一个可以被转换为整数的数字或字符串; 否则,lua_tointeger返回 0 。

    类似函数

    • lua_stringtonumber
    • lua_toboolean
    • lua_tolstring
    • lua_tonumber
    • lua_tostring

    以上这些函数,比较容易理解,本文不做介绍,如有需要,可以自行查阅相关手册。

    示例

    C 控制 lua,以 lua 文件为配置文件示例

    
    /*
     * 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, "width");
        lua_getglobal(L, "height");
        stackDump(L);
    
        //width
        if(!lua_isnumber(L, -2))
        {
            printf("width is not number\n");
            lua_close(L);
            return 0;
        }
    
        //height
        if(!lua_isnumber(L, -1))
        {
            printf("height is not number\n");
            lua_close(L);
            return 0;
        }
        int iHeight = lua_tointeger(L, -2);
        int iWidth = lua_tointeger(L, -1);
    
        printf("Width[%d] Height[%d]\n", iWidth, iHeight);
    
        lua_close(L);
    
        return 0;
    }
    

    lua文件如下

    width=55
    height=50
    

    编译执行结果为:

    '55'   '50'
    Width[50] Height[55]
    

    总结

    C控制lua,将lua当做配置文件,本文只是比较简单的使用示例,比较复杂的配置文件可以使用数据结构table类型的,后续将介绍。

    相关文章

      网友评论

          本文标题:Lua C接口API 3

          本文链接:https://www.haomeiwen.com/subject/kpgrmttx.html