1 upvalue概念

upvalue:嵌套函数的外部函数的局部变量

function func(a) <== 这个函数返回值是一个函数

return function ()

a = a + 1    <== 这里可以访问外部函数func的局部变量a,这个变量a就是upvalue

return a

end

end

func返回一个匿名函数,可用变量接取之。该匿名函数有一个upvalue a(有点像C函数的static变量),初值为首次调用func时的参数

closure概念

closure: 一个匿名函数加上其可访问的upvalue

c = func(1) <== c现在指向一个拥有upvalue a = 1的匿名函数,c也被称作一个闭包

3 C函数如何向LUA递闭包

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n)
这个函数的作用是在栈上压入一个闭包,当一个c函数被创建时, 可以绑定几个值(第三个参数n表面)在它上面, 从而形成一个闭包.  在任何时刻调用这个c函数时, 都可以访问这几个绑定值
绑定的方法: 先一次压入要绑定的n个值到栈上, 然后调用lua_pushcclosure(L, fn, n)这样就形成的一个c闭

static int _counter (lua_State *L)

{

//

//获取第一个upvalue

//

double val = lua_tonumber(L, lua_upvalueindex(1));

lua_pushnumber(L, ++val);

/*

void lua_pushvalue (lua_State *L, int index);

把栈上给定索引处的元素作一个副本压栈。

*/

lua_pushvalue(L, -1);

/*

void lua_replace (lua_State *L, int index);

把栈顶元素放置到给定位置而不移动其它元素(因此覆盖了那个位置处的值),然后将栈顶元素弹出

*/

lua_replace(L, lua_upvalueindex(1));

return 1;  /* return new value */

}

static int counter (lua_State *L)

{

lua_pushnumber(L, 0);

//

//压入初始化第一个upvalue

//

lua_pushcclosure(L, &_counter, 1);

return 1;

}

void testlupvalue()

{

lua_State *L;

L = luaL_newstate();

luaL_openlibs(L);

lua_register(L, "counter", counter);

luaL_loadfile(L, "C:\\c.lua");

lua_pcall(L, 0,0,0);

lua_close(L);

}

closure

LUA upvalues的更多相关文章

  1. lua执行字节码的过程介绍

    前面一篇文章中介绍了lua给下面代码生成最终的字节码的整个过程,这次我们来看看lua vm执行这些字节码的过程. foo = "bar" local a, b = "a& ...

  2. lua解析脚本过程中的关键数据结构介绍

    在这一篇文章中我先来介绍一下lua解析一个脚本文件时要用到的一些关键的数据结构,为将来的一系列代码分析打下一个良好的基础.在整个过程中,比较重要的几个源码文件分别是:llex.h,lparse.h.l ...

  3. Lua string库整理

    string库提供了字符串处理的通用函数. 例如字符串查找.子串.模式匹配等. 当在 Lua 中对字符串做索引时,第一个字符从 1 开始计算(而不是 C 里的 0 ). 索引可以是负数,它指从字符串末 ...

  4. Lua与C的交互

    Lua 与 C 的交互 Lua是一个嵌入式的语言,它不仅可以是一个独立运行的程序,也可以是一个用来嵌入其它应用的程序库. C API是一个C代码与Lua进行交互的函数集,它由以下几部分构成: 1.  ...

  5. Lua 5.1 参考手册

    Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes 云风 译 www.codingno ...

  6. 在C函数中保存状态:registry、reference和upvalues

    C函数可以通过堆栈来和Lua交换数据,但有时候C函数需要在函数体的作用域之外保存某些Lua数据,那么我们想到全局变量或static变量,这样做的缺点是:(1)为Lua设计C函数库时,导致不可重入:(2 ...

  7. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  8. Lua基础

    局部定义与代码块: 使用local声明一个局部变量或局部函数,局部对象只在被声明的那个代码块中有效. 代码块:一个控制结构.一个函数体.一个chunk(一个文件或文本串)(Lua把chunk当做函数处 ...

  9. Lua函数之二

    Lua函数之二 Lua中函数的两个重要特性: 1.函数和其他类型(如number.string)一样,可以存放在变量中,也可以存放在table中,可以作为函数的参数,还可以作为函数的返回值. 2.嵌套 ...

随机推荐

  1. ChibiOS/RT移植到STM32F407

    官网地址:http://www.chibios.org/dokuwiki/doku.php 下载源码 找到STM32F407的demos程序(chibios\demos\STM32\RT-STM32F ...

  2. nginx 之 https 证书配置

    HTTPS原理和作用 为什么需要HTTPS 原因:HTTP不安全 传输数据被中间人盗用.信息泄露 数据内容劫持.篡改 HTTPS协议的实现 对传输内容进行加密以及身份验证 对称加密:加密秘钥和解密秘钥 ...

  3. 一个让Java事半功倍的反射库

    在Java和Android中,我们常常会使用反射来达到一些兼容的目的.Java原生提供的反射很是麻烦,使用起来很是不方便.比如我们想要调UserManager的静态方法get,使用原生的实现如下 tr ...

  4. 【leetcode】266. Palindrome Permutation

    原题 Given a string, determine if a permutation of the string could form a palindrome. For example, &q ...

  5. c# 处理串行化对象的版本变化

  6. c# VS.NET 中的调试工具

  7. java - day019 - 数据库

    https://www.cnblogs.com/myxq666/p/7787744.html Mac 安装MySQL步骤 什么是数据库 数据库: 英文名称Database ,简称 DB 数据库是按照数 ...

  8. 写Django项目的开发工具或者编辑器

    pycharm是写django的最好的编辑器,优先使用pycharm.到官网下载pycharm →https://www.jetbrains.com/pycharm/download→ pycharm ...

  9. 《Python编程:从入门到实践》第二章 变量和简单数据类型 习题答案

    #2.1 print("Hello world!"); #2.2 message="Hello,Python!"; print(message); #2.3 n ...

  10. HTML&CSS基础-相对定位

    HTML&CSS基础-相对定位 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HTML源代码 <!DOCTYPE html> <html> &l ...