美文网首页
Lua C接口API 4

Lua C接口API 4

作者: 小小小码农 | 来源:发表于2016-12-08 20:49 被阅读111次

前面介绍了当lua文件做配置使用时,该如何使用 API 接口去获取配置文件信息, lua 文件作为配置文件使用还是比较方便的,解析程序也比较容易编写,但是前文只介绍了如何 k-v 类型的配置,意味着 k 不能相同。所以本文介绍更高级的使用方式,本人将介绍如何利用lua中的数据结构table来作为配置文件,并在最后介绍 C 如何调用 lua 中的函数。

前言

table作为 lua 语言中的一种数据结构,相对于 C/C++ 语言而言,简直就是 bug 一般的存在,使用真是太方便了,其组合简单易用,可以任意组合成不同的类型 table。本文就介绍如何操作 table 的 API,并示例使用table作为配置数据。

API

下面介绍操作 table 的AP

获取table元素

int lua_getfield (lua_State *L, int index, const char *k);

作用:把 t[k] 的值压栈,这里的 t 是索引指向的值

设置table元素

void lua_setfield (lua_State *L, int index, const char *k);

作用:做一个等价于 t[k] = v 的操作,这里 t 是给出的索引处的值, 而 v 是栈顶的那个值

下面介绍其他相关的函数

判断栈中值得类型

int lua_istable (lua_State *L, int index);

作用:当给定索引的值是一张表时,返回 1 ,否则返回 0 。

int lua_isfunction (lua_State *L, int index);

作用:当给定索引的值是一个函数( C 或 Lua 函数均可)时,返回 1 ,否则返回 0 。

将指定索引值转换成字符串

int lua_isfunction (lua_State *L, int index);

作用:当给定索引的值是一个函数( C 或 Lua 函数均可)时,返回 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已经改变了
    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);

    //调用函数
    lua_getglobal(L, "add");
    if(!lua_isfunction(L, -1))
    {
        printf("It's not function\n");
        lua_close(L);
        return 0;
    }

    //压入参数
    lua_pushnumber(L, 10);  //第一个参数
    lua_pushnumber(L, 20);  //第二个参数

    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

编译执行后结果为:

'table'
'table'   '128'   '123'   '255'
r[128] g[123] b[255]
Ret[30]

总结

lua中table的操作,本文只是介绍简单的结构,table可以互相嵌套组成比较复杂的结构,操作的时候也需要相当的注意。对于API的细节不料及的可以查阅手册,如何设置table中的值,本文只给出了API介绍,并未给出示例,有兴趣的可以自己去尝试下。多多写写代码总归是好的,看得过瘾不如自己找个bug解决来得爽。

相关文章

  • Lua C接口API 4

    前面介绍了当lua文件做配置使用时,该如何使用 API 接口去获取配置文件信息, lua 文件作为配置文件使用还是...

  • Lua C接口API 3

    Lua C 接口 API 接口比较多,主要都是围绕交互栈的操作,前面学习了如何简单操作交互栈,且相应的API比较...

  • Lua C API

    C API 云风Blog:Lua C API 的正确用法 C读取和调用Lua文件的库:lua.h, lauxlib...

  • Lua C接口API 2

    前面学习了如何使用LuaApi操作虚拟栈的栈顶操作,但是仍旧不清楚如何操作栈中的数据,如何获取数据,如何操作数据等...

  • Lua C接口API 1

    最近工作中用到了Lua作为脚本语言由C/C++宿主语言调用,因为之前没用了解过Lua,在使用过程中遇到不少不懂得地...

  • LUA API 参考

    lapi.c和lauxlib.c里包含了大部分的lua的capi。所谓capi是指在c形式的api接口,可以在c/...

  • C++调用lua方式

    目标 使用C++调用lua接口 示例 lua代码(test.lua) C++调用示例(lua_test.cpp) ...

  • LuaC API

    Lua C APi 总结 Lua_newtable(L) 创建table并放到栈顶 lua_pushstring(...

  • tolua

    Using Lua API and tag method facilities, tolua maps C/C++...

  • lua_newstate

    version 5.3.5 1、lua_newstate是由lstate.c提供的lua内部函数,由LUA_API...

网友评论

      本文标题:Lua C接口API 4

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