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

     C函数能够通过堆栈来和Lua交换数据,但有时候C函数须要在函数体的作用域之外保存某些Lua数据。那么我们想到全局变量或static变量,这样做的缺点是:(1)为Lua设计C函数库时,导致不可重入。(2)不是全部的Lua值都能非常好的保存到C变量中。那么可不能够将值保存在Lua全局变量里面呢,能够,Lua就提供了一个独立的被称为registry的表,可是Lua代码本身不能訪问它。

1、registry全局注冊表
解释:一个普通的Lua表,使用假索引(pseudo-index)LUA_REGISTRYINDEX訪问。C代码能够訪问。Lua代码不能訪问。

用途:解决C函数保留全局Lua值的问题。

注意:全部的C库共享同样的registry,所以对于key的命名须要具有全局唯一性。

// 获取registry表键值"KEY"相应的值的方法:lua_pushstring(L, "KEY");lua_gettable(L, LUA_REGISTRYINDEX);

2、reference引用系统
解释:通过一个整数来唯一标识一个Lua数据对象,由两个函数luaL_ref和luaL_unref组成,这对函数用来不须要操心名称冲突的将值保存到registry中去。
用途:将一个指向Lua值的reference存储到一个C结构体中,这个reference是一个int的KEY。

注意:栈顶值为nil的时候。不会产生reference。luaL_ref函数会返回LUA_REFNIL,而对LUA_REFNIL解引用是没有效果的。

重要函数:
int luaL_ref (lua_State *L, int t);
创建并返回一个引用reference。并将[reference。栈顶值v]增加t相应的表中。

void luaL_unref (lua_State *L, int t, int ref);
解引用,将t相应的表中的[reference。v]键值对删除。

   // 对栈顶的值v生成一个引用,即将[r, v]存到LUA_REGISTRYINDEX表中int r = luaL_ref(L, LUA_REGISTRYINDEX);// 将一个引用值入栈lua_rawgeti(L, LUA_REGISTRYINDEX, r);// 解引用。即释放reference和值luaL_unref(L, LUA_REGISTRYINDEX, r);

3、upvalues机制
解释:当创建一个C函数时能够关联一些值,这样就创建了一个C闭包,这些关联值就叫做upvalues。

用途:实现了与C static变量等价的概念,这样的变量仅仅能在特定的函数内可见。
使用:通过lua_upvalueindex(n)生成假索引来訪问。

    // 预声明static int counter (lua_State *L);// 创建C闭包的工厂函数int newCounter (lua_State *L){lua_pushnumber(L, 0);lua_pushcclosure(L, &counter, 1);return 1;}// C函数static int counter (lua_State *L){double val = lua_tonumber(L, lua_upvalueindex(1));lua_pushnumber(L, ++val);   /* new value */lua_pushvalue(L, -1);       /* duplicate it */lua_replace(L, lua_upvalueindex(1));  /* update upvalue */return 1;  /* return new value */}

注意:永远不要使用数字作为registry 的key。由于这样的类型的key是保留给reference系统使用。
假索引(pseudo-index)的特点:(1)相应的值不在栈中。(2)使用方式类似于栈索引。大多数接受索引为參数的函数都能使用。(3)那些操作栈本身的函数不能使用假索引,比方lua_remove,lua_insert等。

与Lua闭包(在Lua代码中,一个闭包是一个从外部函数訪问局部变量的函数)不同的是。C闭包不能共享upvalues:每个闭包都有自己独立的变量集。然而。我们能够设置不同函数的upvalues指向同一个表。这样这个表就变成了一个全部函数共享数据的地方。

在C 函数中保存状态:registry、reference和upvalues相关推荐

  1. 程序中保存状态的方式之Cookies

    程序中保存状态的方式之 Cookies,之前写过一篇关于ViewState的.现在继续总结Cookies方式的 新建的测试页面login <%@ Page Language="C#&q ...

  2. Spring MVC不要在@Service bean中保存状态

    先看这么一段代码: @Service public class AccountService {private String message;public void foo1() {if (true) ...

  3. react怎么存上一页_如何实现 React 中的状态自动保存?

    什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目, ...

  4. 失败狮计划——在localStorage中保存vuex状态

    前言 最近碰到了这么一个需求变动:在当前页点击一个按钮打开一个新的页签(本来是在当前页通过路由跳转进入一个新的组件),对于传统jq项目来说这个应该是不费吹灰之力可以实现的,但是对于vue项目来说就要好 ...

  5. react大数据量渲染_React 中的状态自动保存(KeepAlive)

    什么是状态保存?假设有下述场景:移动端中,用户访问了一个列表页,上拉浏览列表页的过程中,随着滚动高度逐渐增加,数据也将采用触底分页加载的形式逐步增加,列表页浏览到某个位置,用户看到了感兴趣的项目,点击 ...

  6. html 存储登录状态,Vue中保存用户登录状态实例代码

    首先我们假设,这里的登录组件(register.vue)是App.vue组件的子组件,是通过路由进入登录组件的. 登录组件中用户点击登录后,后台会传过来一个用户名,我的App.vue组件中需要拿到这个 ...

  7. matlab保存之前的函数,MATLAB中定义函数并保存后怎么运行啊?

    你这个2113要求有点奇怪.5261tif格式的数据就4102应该是整型的1653,你为什么一专定要把浮点数写到tif文件呢属?一个浮点数占8个字节,而一个uint8只占一个字节,从图像数据来说,rg ...

  8. vue3函数写法中的状态、函数定义

    vue3中有两种写法:类写法.函数写法(hooks) 类写法跟vue一样,函数写法是新增的: 状态是什么: 页面中要显示的东西,放在一个变量中,每次更改完值,就会被拦截,同时再重新渲染页面: 状态的对 ...

  9. Linux-C基础知识学习:C语言作业-将5个学生成绩保存在一个数组中,单独实现一个计算平均成绩的average函数, 在main函数中获取该函数返回的平均值,并打印。

    Linux基础知识学习 C语言作业:将5个学生成绩保存在一个数组中,单独实现一个计算平均成绩的average函数, 在main函数中获取该函数返回的平均值,并打印. #include <stdi ...

最新文章

  1. 自古帝王多短命,假如皇帝也懂负载均衡算法...
  2. 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  3. 串结构练习——字符串匹配 解题报告
  4. 记录一个找问题的经过
  5. Ubuntu中文输入法崩溃问题(候选框乱码)
  6. 每天一道LeetCode-----字符串乘法
  7. mysql流式查询mybatis_流式查询:MyBatis千万级数据查询解决方案,避免OOM
  8. Java基础知识——Java集合详解
  9. python文本分类算法_Python-基于向量机SVM的文本分类
  10. 人脸识别的三个评测标准
  11. ajax调用微信退款接口,微信退款(在.net core 用http方式请求)
  12. 新版Android使用微桌面,微桌面是什么?微信正开发安卓“微桌面”
  13. java ppt转图片,怎么用POI将PPT的内容转换为图片
  14. 北京内推 | 秘塔科技招聘NLP算法工程师(社招校招可转正实习)
  15. Java—sql关于不同条件下合并结果
  16. php 跳转邮箱,JS点击跳转登陆邮箱功能简单的实现方法
  17. 1103 缘分数 (20 分)
  18. 戴尔t7610服务器安装系统,Dell Poweredge R730服务器系统安装和配置详细教程
  19. dynamic_cast用法总结
  20. twitter账号解封

热门文章

  1. pycharm如何在程序运行后查看变量的值,变量的类型(不通过print和debug的方式)
  2. opencv python 中cv2.putText()函数的用法
  3. Java的ArrayList集合_JAVA之ArrayList集合
  4. RequestParam注解在required设置为true时失效
  5. mysql中的索引对查询的影响
  6. 网络编程学习笔记(RES_USE_INET6解析器选项)
  7. HDU2016 数据的交换输出
  8. mybatis 中#和$的区别
  9. poj 3984 迷宫问题 BFS
  10. 坐在宝座上圣洁羔羊 男声N重唱