Lua api(三)

前言#

上一篇文章讲了两个比较简单的api,今天我们来看两个稍微难理解的,也是实现lua和C++交互的,其中这两个api可能会涉及到事件的原方法,我们今天先引出来但是不做详细解释,在接下来的一章中将会给出例子,用来解释什么是元方法。

官方澳门新永利下载 1gettable.png

总结#

  • 注意例子中lua_getfield和lua_setfield方法的使用。
  • 注意在程序过程中虚拟堆栈的变化情况,保持堆栈在函数执行前后不变是一个良好的习惯。
  • 学会使用c来调用lua方法的写法。
  • 我们一开始在lua脚本中实现了index和newindex方法是为了记录两个api是否会触发元表,结果和我们想的一样,lua_gettable和lua_settable确实触发了元表操作。
  • 注意lua_gettable和lua_settable在c/c++中调用的方法,注意参数的压栈顺序。
  • 获取lua变量时记得判断一下变量值是否为nil,然后做出相应调整,这样可以避免一些不必要的麻烦。

内容#


Usage##

  • 首先我们来编写一个lua文件,文件命名为fieldtest.lua,代码内容如下:

-- 变量系数
param =
{
    a = 2;
    b = 1;
}

-- 全局变量,满足c=2a+b,在c语言中实现
c = 100;

-- f(x) = ax + b
function lua_func(x)
    return (param.a * x * x + param.b * x + c)
end
  • 接下来我们来编写C语言函数,代码如下:

void print_stacknum(const char * desc, const int count)
{
    printf("%s stack num = %dn",desc, count);
}

void test_api_getfield()
{
    lua_State *L = lua_open();

    luaL_dofile(L,"fieldtest.lua");     // 加载执行lua文件
    lua_getglobal(L,"param");           // 查找param变量压入栈底
    print_stacknum("stage1", lua_gettop(L));

    lua_getfield(L, -1, "a");           // 将Param.a入栈
    int nParam_a = lua_tointeger(L,-1); // 将Param.a取出赋值给变量nParam_a
    lua_getfield(L, -2, "b");           // 将Param.b入栈
    int nParam_b = lua_tointeger(L,-1); // 将Param.b取出赋值给变量nParam_b
    print_stacknum("stage2",lua_gettop(L));

    lua_pop(L, 3);                  // 清除掉栈中多余的3个变量param、param.a、param.b
    print_stacknum("stage3",lua_gettop(L));

    int nParam_c = 2 * nParam_a + nParam_b;
    lua_pushinteger(L, nParam_c);       // 将c=2a+b计算完成,压入栈顶
    lua_setfield(L, LUA_GLOBALSINDEX, "c");// 使用栈顶的值设置脚本全局变量c
    print_stacknum("stage4",lua_gettop(L));

    lua_getglobal(L,"lua_func");        // 查找lua_func函数压入栈底
    lua_pushinteger(L, 3);              // 压入函数变量x=3    
    lua_pcall(L,1,1,0);             // 执行脚本函数lua_func
    print_stacknum("stage5",lua_gettop(L));

    int result = lua_tointeger(L,-1);   // 从栈中取回返回值 
    lua_pop(L,1);                       // 弹出返回结果
    print_stacknum("stage6",lua_gettop(L));

    printf("nresult = %d", result);  
    lua_close(L);                       //关闭lua环境  
}
  • 结果

官方澳门新永利下载 2

fieldtest.png

lua_getfield##

  • 官方澳门新永利下载,原型:void lua_getfield (lua_State *L, int index, const char
    *k);
  • 解释:把 t[k] 值压入堆栈, 这里的 t 是指有效索引 index 指向的值。
    在 Lua 中,这个函数可能触发对应 “index”
    事件的元方法。

  • 首先我们来新建一个文件,将文件命名为gettabletest.lua编写如下代码:

lua_setfield##

  • 原型:void lua_setfield (lua_State *L, int index, const char
    *k);
  • 解释:这个函数将把这个值弹出堆栈。 跟在 Lua
    中一样,这个函数可能触发一个 “newindex”
    事件的元方法。

  • 接下来我们编写c++代码如下:

发表评论

电子邮件地址不会被公开。 必填项已用*标注