lua的closure创建和使用
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创建和使用相关推荐
- C#调用Lua 3、创建Lua解析器管理器
首先为什么我们需要一个Lua解析器管理器? 因为每次创建一个新的C#调用lua类时,我们都需要创建一个lua解析器,步骤重复,且难以保证解析器唯一性.因此创建一个lua解析器管理类,来保证LuaEnv ...
- [转载]Lua和C++交互详细总结
原文请看:Lua和C++交互详细总结 转自:http://cn.cocos2d-x.org/tutorial/show?id=1474 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. ...
- Lua和C++交互详细总结
一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈.栈的特点是先进后出. 在Lua中,Lua堆栈就是一个struct ...
- 【lua学习】6.函数,闭包,错误处理
1 数据结构和宏 1.1 Closure 闭包 1.2 Proto 函数原型 1.3 UpVal 外部局部变量(upvalue) 1.4 LocVar 局部变量信息 1.5 SParser 语法分析所 ...
- 解决方案:Lua环境搭建
解决方案:Lua环境搭建 一.Lua简介 Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放,其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能.Lua 是巴西里 ...
- 第5章.网站首页高可用nginx+lua
第5章 网站首页高可用nginx+lua 学习目标 了解Lua语言的基本语法 使用nginx+Lua+redis实现广告缓存 掌握nginx限流的基本使用方法 1 Lua介绍 1.1 lua是什么 ...
- QQ邮箱记事本模块Lua实现小结
QQ邮箱是一个除了收邮件和发邮件的基本功能之外,具有其它一些小的办公功能的邮箱客户端.其中记事本是办公功能之一. 但是集成了记事本等小功能的邮箱,体积较大.为控制客户端体积,需要将非基本功能的一些功能 ...
- Lua和C++交互详细总结【转载】
[转] 原文 已丢失转自 链接 .备份.侵删 一.Lua堆栈 要理解Lua和C++交互,首先要理解Lua堆栈. 简单来说,Lua和C/C++语言通信的主要方法是一个无处不在的虚拟栈.栈的特点是先进后出 ...
- Lua基本语法-书写规范以及自带常用函数
Lua基本语法-书写规范和常用函数 本文提供全流程,中文翻译. Chinar坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 String O ...
最新文章
- 【Flocking、PPO无人机群控制算法】基于Flocking和PPO深度强化学习的无人机群控制算法的MATLAB仿真
- Java基础篇:final关键字
- python不能安装pip_python – 无法安装pip:权限被拒绝错误
- Wi-Fi和WLAN有什么区别
- python中对文件进行读和写
- Cisco ACS AAA服务器导入华为私有属性
- php程序里的configini_PHP读取配置文件类实例(可读取ini,yaml,xml等)
- UVA11005 Cheapest Base【数学】
- git “errno=Connection refused”
- HP server ILO
- Kalman Filter—Step by step Derivation of Kalman Gain
- Vue检测web端和移动端,并强制手机横屏
- mac谷歌浏览器怎么登陆账户_苹果电脑怎么安装谷歌浏览器_macbook如何下载安装谷歌浏览器-win7之家...
- shapely包的使用
- Leetcode1278
- oracle数据库审计优点缺点,Oracle数据库安全性:标准数据库审计
- PHPcmsv9采集免规则PHPcmsv9采集
- B. TMT Document—— Codeforces Round #715 (Div. 2)
- 485通讯协议在java中的应用
- 【答读者问24】作为一个大一新生,如果我想要成为一个quant,我需要做些什么呢?