1. 注册表

注册表是一个普通的table,我们可以将c函数中需要保存的状态都存储在注册表中,注册表是可以被多个c模块共享的。

由于注册表是一个普通table,我们同样可以在栈中对其进行操作,只是这个table的索引是由一个常量LUA_REGISTRYINDEX进行索引。

如何向注册表中存入一个值对:

lua_pushstring(L, "hello");

lua_setfield(L, LUA_REGISTRYINDEX, "key");

lua_getfield(L, LUA_REGISTRYINDEX, "key");

如何向注册表中存入数组元素:

lua_pushstring(L, "i am a student");

int key = luaL_ref(L, LUA_REGISTRYINDEX); // 由于注册表的数组中已经存放了部分元素,因此不能使用自定义的索引,必须使用系统提供的函数,就无须关心索引的问题

                       // 成功调用后,会返回一个当前元素的索引

lua_rawgeti(L, LUA_REGISTRYINDEX, key);

2. upvalue:

upvalue机制提供了一种能和c函数关联起来的数据,upvalue可以保存一个lua值,然后可以将任意多的upvalue和c函数关联。在调用该c函数的时候,我们就可以提取和该函数关联的所有upvalue,这种技术又叫c closure。。即时用同一函数创建的closure,它们之间都是相互独立,即它们都拥有自己的upvalue。

如何创建一个c closure:

static int counter (lua_State* L) { // 同样我们需要创建我们的函数,和普通c函数一样

  int value = lua_tonumber(L, lua_upvalueindex(1)); // 提取第一个upvalue,这里有2个upvalue

  value *= 2;

  lua_pushnumber(L, value);

  return 1;

}

int newcounter (lua_State* L) { // 用于创建c closure的函数

  lua_pushnumber(L, 1);  // 将所有upvalue值都压入栈,这些值大多数情况是lua调用时候传入的参数

  lua_pushstring(L, "234");

  lua_pushcclosure(L, &counter, 2); // 创建c closure,c函数是counter,最后一个参数是2,代表从栈顶开始向下的2个值都作为c closure的upvalue

  return 1

}

实例:

c代码:

int t_tuple (lua_State* L) {
int op = luaL_optint(L, , );
if (op == ) {
int i;
for (i = ; !lua_isnone(L, lua_upvalueindex(i)); ++i) {
lua_pushvalue(L, lua_upvalueindex(i));
}
return i - ;
}
else {
luaL_argcheck(L, op > , , "index out of range");
if (lua_upvalueindex(op) == LUA_TNONE)
return ;
else {
lua_pushvalue(L, lua_upvalueindex(op));
return ;
}
}
} int t_new (lua_State* L) {
int top = lua_gettop(L);
lua_pushcclosure(L, t_tuple, top);
return ;
}

lua代码:

local t = new (, , "hello");
print(t())
print(t())

在c中保存状态的更多相关文章

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

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

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

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

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

    在C函数中保存状态:registry.reference和upvalues      C函数能够通过堆栈来和Lua交换数据,但有时候C函数须要在函数体的作用域之外保存某些Lua数据.那么我们想到全局变 ...

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

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

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

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

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

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

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

    原文:[置顶] Android菜鸟的成长笔记(14)—— Android中的状态保存探究(上) 我们在用手机的时候可能会发现,即使应用被放到后台再返回到前台数据依然保留(比如说我们正在玩游戏,突然电话 ...

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

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

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

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

随机推荐

  1. ubuntu 编译oce Open CASCADE

    前期准备 1 安装cmake 最新版本 sudo apt-get install cmake 2 安装OpenGl Library 和OpenGL Utilities sudo apt-get ins ...

  2. BZOJ 1969 树链剖分+Tarjan缩点

    发现自己Tarjan的板子有错误.发现可以用Map直接删去边,Get. 听说std是双连通.LCA.并查集.离线思想.用BIT维护dfs序和并查集维护LCA的动态缩点的好题 #include < ...

  3. js 轮播图代码

    js代码 (function(){ /** parent //父容器 changeTime //每次间隔几秒切换下一条 leaveTime //鼠标从小图上离开过后几秒继续切换 index //从第几 ...

  4. IOS网络开发(二)

    1 局域网群聊软件 1.1 问题 UDP协议将独立的数据包从一台计算机传输到另外一台计算机,但是并不保证接受方能够接收到该数据包,也不保证接收方所接收到的数据和发送方所发送的数据在内容和顺序上是完全一 ...

  5. Python 利用pytesser模块识别图像文字

    使用的是python的pytesser模块,原先想做的是图片中文识别,搞了一段时间了,在中文的识别上还是有很多问题,这里做记录分享. pytesser,OCR in Python using the ...

  6. Thrift 个人实战--RPC服务的发布订阅实现(基于Zookeeper服务)

    前言: Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还 ...

  7. CheckBoxList 用法

    <asp:CheckBoxList ID="cblqf" ForeColor="#4d6fc8" runat="server" Rep ...

  8. Trapping Rain Water

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  9. 【渗透测试学习平台】 web for pentester -4.XML

    example1: http://192.168.91.139/xml/example1.php?xml=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%2 ...

  10. my Js

    1. __doPostBack是.net自动生成的(当页面中有LinkButton.DropDownList(AutoPostBack)等时:Button和ImageButton不会生成它,也不会调用 ...