在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. 在C函数中保存状态:registry、reference和upvalues

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

  2. LUA 在C函数中保存状态:registry、reference

    1 背景 lua的值一般都是保存在栈里面,调用函数完毕值在栈会被清掉,从而被GC回收.但有时候C函数需要在函数体的作用域之外保存某些Lua数据,这些数据不能存放在栈里面,有没有全局变量之类的可以存放. ...

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

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

  4. 程序中保存状态的方式之ViewState

    程序中保存状态的方式有以下几种: 1.Application 2.Cookie 3.Session 4.ViewState:ViewState是保存状态的方式之一,ViewState实际就是一个Hid ...

  5. 在c中保存状态

    1. 注册表 注册表是一个普通的table,我们可以将c函数中需要保存的状态都存储在注册表中,注册表是可以被多个c模块共享的. 由于注册表是一个普通table,我们同样可以在栈中对其进行操作,只是这个 ...

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

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

  7. Android菜鸟的成长笔记(15)—— Android中的状态保存探究(下)

    原文:Android菜鸟的成长笔记(15)-- Android中的状态保存探究(下) 在上一篇中我们简单了解关于Android中状态保存的过程和原理,这一篇中我们来看一下在系统配置改变的情况下保存数据 ...

  8. 【React】377- 实现 React 中的状态自动保存

    点击上方"前端自习课"关注,学习起来~ 作者:陈俊宇 https://github.com/CJY0208 什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉 ...

  9. 19.在HTTP 1.0中,状态码401的含义是(?);如果返回“找不到文件”的提示,则可用 header 函数,其语句为(?)写出http常见的状态码和含义,至少5个.[完善题目]

    状态401代表未被授权,header("Location:www.xxx.php"); 100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. 300 ...

随机推荐

  1. Linux - 环境变量与位置变量

    环境变量 [root@local ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin 注:只有自己执行 ...

  2. vs2015编译使用GRPC

    1.获取源码:位于github上 电脑装有git的直接克隆,未装git下载压缩包也可以 git clone  https://github.com/grpc/grpc.git cd grpc git ...

  3. 院校-美国:麻省理工学院(MIT)

    ylbtech-院校-美国:麻省理工学院(MIT) 麻省理工学院(Massachusetts Institute of Technology),简称麻省理工(MIT),坐落于美国马萨诸塞州波士顿都市区 ...

  4. A - Presents

    Problem description Little Petya very much likes gifts. Recently he has received a new laptop as a N ...

  5. Datatable筛选数据

    DataRow[] drArr = dt.Select("C1=’abc’");//查询 还可以这样操作: DataRow[] drArr = dt.Select("C1 ...

  6. ffmpeg编码

    1. 注册所有容器格式和CODEC:av_register_all()2. 打开文件:av_open_input_file()3. 从文件中提取流信息:av_find_stream_info()4. ...

  7. java keytool证书工具使用小结(转载)

    原文地址:http://www.micmiu.com/lang/java/keytool-start-guide/ Keytool 是一个Java数据证书的管理工具 ,Keytool将密钥(key)和 ...

  8. Boost锁~临界区保护和临界资源共享

    前言: 除了thread,boost::thread另一个重要组成部分是mutex,以及工作在mutex上的boost::mutex::scoped_lock.condition和barrier,这些 ...

  9. 03--(二)编程实践中C语言的一些常见细节

    编程实践中C语言的一些常见细节(转载) 对于C语言,不同的编译器采用了不同的实现,并且在不同平台上表现也不同.脱离具体环境探讨C的细节行为是没有意义的,以下是我所使用的环境,大部分内容都经过测试,且所 ...

  10. IOS Html富文本渲染方式:DTCoreText、WKWebView、UIWebView的内存占用对比

    在app的内容页(详情页)中,富文本的显示一直是经常需要处理的问题,而通常在后端的富文本编辑中,Html应用比较普遍,所以其实需要处理的Html富文本显示的问题,以下这三种方式肯定不是最优的显示Htm ...