• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

lua的closure创建和使用

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

    lua的闭包包括CClosure和FClosure两种类型。下面的例子介绍如何在C中使用C创建的闭包函数,C中使用lua中创建的闭包函数,Lua中使用C中创建的闭包函数,Lua中使用Lua闭包就不赘述了。

    C中通过lua_pushclosure创建闭包函数,在将闭包函数推到堆栈之前需要先把n个上值推到lua_state上。取用的时使用lua_upvalueindex(n)取的特定索引上的上值,更改的话可以使用lua_replace更改上值。例子中每次将上值+5,因此在lua中每次调用upvalue_test函数都会获得正确的上值。lua中的closure想在C中进行upvalue的更改有一点麻烦,首先你需要获取closure函数对象,使用lua_getupvalue将特定索引上的上值放到栈顶,可以使用lua_setupvalue重设上值。如果你的fclosure中没有使用全局变量,那么其上值索引应该是按照local变量的声明顺序来的,但是一旦使用了全局变量,第一个上值必定是_ENV环境,也就是说你可以通过重新设置_ENV环境,修改全局的上值,这也是修改环境变量的一种方法。

    C 文件:

#include <stdio.h>
#include <string.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <dlfcn.h>
#include <math.h>

static int mytest(lua_State *L) {
  //获取上值
  int upv = (int)lua_tonumber(L, lua_upvalueindex(1));
  printf("%d\n", upv);
  upv += 5;
  lua_pushinteger(L, upv);
  lua_replace(L, lua_upvalueindex(1));

  //获取一般参数
  printf("%d\n", (int)lua_tonumber(L,1));

  return 0;
}

int main(void) {
  lua_State *L = luaL_newstate();
  luaL_openlibs(L);

  //设置Cclosure函数的上值
  lua_pushinteger(L,10);
  lua_pushinteger(L,11);
  lua_pushcclosure(L,mytest,2);
  lua_setglobal(L,"upvalue_test");
  luaL_dofile(L, "./luatest.lua");

  //获取fclosure上值的名称(临时值, 不带env)
  lua_getglobal(L, "l_counter");
  const char *name = lua_getupvalue(L, -1, 1);
  printf("%s\n", name);

  //设置fclosure上值
  lua_getglobal(L, "l_counter");
  lua_pushinteger(L,1000);
  name = lua_setupvalue(L, -2, 1);
  printf("%s\n", name);

  lua_getglobal(L,"ltest");
  lua_pcall(L,0,0,0);
  lua_getglobal(L,"ltest");
  lua_pcall(L,0,0,0);

  //获取fclosure的上值(带env)
  lua_getglobal(L, "g_counter");
  lua_getupvalue(L, -1, 1);
  
  //通过settable重新设置env中对应的值
  lua_pushstring(L, "gloval_upvalue");
  lua_pushinteger(L,10000);
  lua_settable(L,-3);
  
  lua_pushstring(L, "gloval_upvalue1");
  lua_pushinteger(L,20000);
  lua_settable(L,-3);
  
  lua_getglobal(L,"gtest");
  lua_pcall(L,0,0,0);
  lua_close(L);
  return 0;
}

  Lua 文件

     

gloval_upvalue = 10
gloval_upvalue1 = 20
local local_upvalue = 100

function l_counter()
   return function ()
      local_upvalue = local_upvalue + 1
      return local_upvalue
   end
end

function g_counter()
   return function ()
      gloval_upvalue = gloval_upvalue + 1
      return gloval_upvalue,gloval_upvalue1
   end
end

g_testf = g_counter()
l_testf = l_counter()

function gtest()
  print(g_testf())
end


function ltest()
  print(l_testf())
end

upvalue_test(1,2,3)
upvalue_test(4,5,6)

  


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
RichLabel基于Cocos2dx+Luav3.x发布时间:2022-07-22
下一篇:
lua创建文件发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap