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 = 100function l_counter()return function ()local_upvalue = local_upvalue + 1return local_upvalueend
endfunction g_counter()return function ()gloval_upvalue = gloval_upvalue + 1return gloval_upvalue,gloval_upvalue1end
endg_testf = g_counter()
l_testf = l_counter()function gtest()print(g_testf())
endfunction ltest()print(l_testf())
endupvalue_test(1,2,3)
upvalue_test(4,5,6)

  

转载于:https://www.cnblogs.com/biyeqingfeng/p/4990101.html

lua的closure创建和使用相关推荐

  1. C#调用Lua 3、创建Lua解析器管理器

    首先为什么我们需要一个Lua解析器管理器? 因为每次创建一个新的C#调用lua类时,我们都需要创建一个lua解析器,步骤重复,且难以保证解析器唯一性.因此创建一个lua解析器管理类,来保证LuaEnv ...

  2. [转载]Lua和C++交互详细总结

    原文请看:Lua和C++交互详细总结 转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. ...

  3. Lua和C++交互详细总结

    一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈.栈的特点是先进后出. 在Lua中,Lua堆栈就是一个struct ...

  4. 【lua学习】6.函数,闭包,错误处理

    1 数据结构和宏 1.1 Closure 闭包 1.2 Proto 函数原型 1.3 UpVal 外部局部变量(upvalue) 1.4 LocVar 局部变量信息 1.5 SParser 语法分析所 ...

  5. 解决方案:Lua环境搭建

    解决方案:Lua环境搭建 一.Lua简介 Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能.Lua 是巴西里 ...

  6. 第5章.网站首页高可用nginx+lua

    第5章 网站首页高可用nginx+lua 学习目标 了解Lua语言的基本语法 使用nginx+Lua+redis实现广告缓存 掌握nginx限流的基本使用方法 1 Lua介绍 1.1 lua是什么 ​ ...

  7. QQ邮箱记事本模块Lua实现小结

    QQ邮箱是一个除了收邮件和发邮件的基本功能之外,具有其它一些小的办公功能的邮箱客户端.其中记事本是办公功能之一. 但是集成了记事本等小功能的邮箱,体积较大.为控制客户端体积,需要将非基本功能的一些功能 ...

  8. Lua和C++交互详细总结【转载】

    [转] 原文 已丢失转自 链接 .备份.侵删 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈.栈的特点是先进后出 ...

  9. Lua基本语法-书写规范以及自带常用函数

    Lua基本语法-书写规范和常用函数 本文提供全流程,中文翻译. Chinar坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 String O ...

最新文章

  1. 【Flocking、PPO无人机群控制算法】基于Flocking和PPO深度强化学习的无人机群控制算法的MATLAB仿真
  2. Java基础篇:final关键字
  3. python不能安装pip_python – 无法安装pip:权限被拒绝错误
  4. Wi-Fi和WLAN有什么区别
  5. python中对文件进行读和写
  6. Cisco ACS AAA服务器导入华为私有属性
  7. php程序里的configini_PHP读取配置文件类实例(可读取ini,yaml,xml等)
  8. UVA11005 Cheapest Base【数学】
  9. git “errno=Connection refused”
  10. HP server ILO
  11. Kalman Filter—Step by step Derivation of Kalman Gain
  12. Vue检测web端和移动端,并强制手机横屏
  13. mac谷歌浏览器怎么登陆账户_苹果电脑怎么安装谷歌浏览器_macbook如何下载安装谷歌浏览器-win7之家...
  14. shapely包的使用
  15. Leetcode1278
  16. oracle数据库审计优点缺点,Oracle数据库安全性:标准数据库审计
  17. PHPcmsv9采集免规则PHPcmsv9采集
  18. B. TMT Document—— Codeforces Round #715 (Div. 2)
  19. 485通讯协议在java中的应用
  20. 【答读者问24】作为一个大一新生,如果我想要成为一个quant,我需要做些什么呢?

热门文章

  1. Spring3基于注释驱动的AOP
  2. js中判断两个数字的大小
  3. android FloatingActionButton
  4. Android应用博客目录
  5. FineUIMvc随笔(1)动态创建表格列
  6. x位全排列(next_permutation)
  7. Toad 登陆数据库
  8. 转载——Java与WCF交互(一):Java客户端调用WCF服务
  9. [LeetCode 111] - 二叉树的最小深度 (Minimum Depth of Binary Tree)
  10. sharepoint 不同路径下 COOKIE找不到