LUA 在C函数中保存状态:registry、reference
1 背景
lua的值一般都是保存在栈里面,调用函数完毕值在栈会被清掉,从而被GC回收。但有时候C函数需要在函数体的作用域之外保存某些Lua数据,这些数据不能存放在栈里面,有没有全局变量之类的可以存放。答案是肯定的,Lua就提供了一个独立的被称为registry的表,但是Lua代码本身不能访问它
2 registry全局注册表
Lua 提供一个独立的被称为 registry 的表, C 可以自由使用,但 Lua 代码不能访问他。索引:LUA_REGISTRYINDEX, 所有的C库共享相同的registry(如果一些全局数据只想本模块可见,可以使用LUA_ENVIRONINDEX,LUA_ENVIRONINDEX只有本模块注册的所有C函数可见),所以对于key的命名需要具有全局唯一性,
永远不要使用数字作为registry 的key,因为这种类型的key是保留给reference系统使用.比如
const char* key1 = "key1";
lua_pushstring(L1, (const char*)key1);
lua_pushnumber(L1, 100);
/* registry[Key] = 100 */
lua_settable(L1, LUA_REGISTRYINDEX);
//
//get
//
lua_pushstring(L, (const char*)key1); /* push address */
lua_gettable(L, LUA_REGISTRYINDEX); /* retrieve value */
int myNumber = lua_tonumber(L, -1); /* convert to number */
3 reference引用系统
registry 表全局唯一的,你需要自己push一个唯一的key, 这样你很难确保key多依然是唯一的,系统最好能帮我们维护一个唯一的值来表示LUA值,那就是引用系统。通过一个整数来唯一标识一个Lua数据对象,由两个函数luaL_ref和luaL_unref组成,这对函数用来不需要担心名称冲突的将值保存到registry中去
int luaL_ref (lua_State *L, int t);
栈顶是要保存的lua的值,t是表示要存放到的table在栈的位置,如果使用全局registey表来保存,那只需要填LUA_REGISTRYINDEX。调用完之后会之后会pop栈顶的对象
void luaL_unref (lua_State *L, int t, int ref);
解引用,ref是luaL_ref 返回的值,t是表示要存放到的table在栈的位置,如果使用全局registey表来保存,那只需要填LUA_REGISTRYINDEX
void (lua_rawgeti) (lua_State *L, int t, int n);
获取保存的lua值,调用完之后lua值就存放到栈顶了, t是表示要存放到的table在栈的位置,如果使用全局registey表来保存,那只需要填LUA_REGISTRYINDEX,n就是luaL_ref 的返回值
4 reference使用例子
假设我们通过luaL_loadstring加载要执行的LUA脚本,后面每想创建线程运行加载的脚本,但又不想每创建一个线程都luaL_loadstring一遍,这样性能低,咱办
lua_State *L;
L = luaL_newstate();
luaL_openlibs(L);
luaL_loadstring(L, "print(\"hello lua\")");
//
//编译好的数据先保存起来,加快性能.
//
int codeid = luaL_ref (L, LUA_REGISTRYINDEX);
for( int i = 0; i < 10; i++)
{
//
//创建线程.
//
lua_State *L1 = lua_newthread(L);
//
//把数据入栈继续调用.
//
lua_rawgeti (L, LUA_REGISTRYINDEX, codeid);
//
//把栈顶的函数复制到新线程的栈里面,然后再POP
//
//void lua_xmove (lua_State *from, lua_State *to, int n);
lua_xmove(L, L1, 1);
lua_pop(L, 1);
BOOL x = lua_resume(L1, 0);
}
lua_close(L);
LUA 在C函数中保存状态:registry、reference的更多相关文章
- 在C 函数中保存状态:registry、reference和upvalues
在C函数中保存状态:registry.reference和upvalues C函数能够通过堆栈来和Lua交换数据,但有时候C函数须要在函数体的作用域之外保存某些Lua数据.那么我们想到全局变 ...
- 在C函数中保存状态:registry、reference和upvalues
C函数可以通过堆栈来和Lua交换数据,但有时候C函数需要在函数体的作用域之外保存某些Lua数据,那么我们想到全局变量或static变量,这样做的缺点是:(1)为Lua设计C函数库时,导致不可重入:(2 ...
- 程序中保存状态的方式之Cookies
程序中保存状态的方式之 Cookies,之前写过一篇关于ViewState的.现在继续总结Cookies方式的 新建的测试页面login <%@ Page Language="C#&q ...
- 程序中保存状态的方式之ViewState
程序中保存状态的方式有以下几种: 1.Application 2.Cookie 3.Session 4.ViewState:ViewState是保存状态的方式之一,ViewState实际就是一个Hid ...
- 在c中保存状态
1. 注册表 注册表是一个普通的table,我们可以将c函数中需要保存的状态都存储在注册表中,注册表是可以被多个c模块共享的. 由于注册表是一个普通table,我们同样可以在栈中对其进行操作,只是这个 ...
- Spring MVC不要在@Service bean中保存状态
先看这么一段代码: @Service public class AccountService { private String message; public void foo1() { if (tr ...
- [lua] 你所不知道的lua nil值在可变参数函数中怎么处理!
在lua中, 问题1:如果你在可变参数...中传入若干个参数,其中有的参数要带nil,这时怎么解决呢?(比如local function _test(...) end _test(1, nil, ...
- 【React】377- 实现 React 中的状态自动保存
点击上方"前端自习课"关注,学习起来~ 作者:陈俊宇 https://github.com/CJY0208 什么是状态保存? 假设有下述场景: 移动端中,用户访问了一个列表页,上拉 ...
- 19.在HTTP 1.0中,状态码401的含义是(?);如果返回“找不到文件”的提示,则可用 header 函数,其语句为(?)写出http常见的状态码和含义,至少5个.[完善题目]
状态401代表未被授权,header("Location:www.xxx.php"); 100-199 用于指定客户端应相应的某些动作. 200-299 用于表示请求成功. 300 ...
随机推荐
- TortoiseSVN-1.7.12.24070-x64-svn-1.7.9安装包和汉化包
链接:https://pan.baidu.com/s/1NbrQW44N_kTh7VN0Fz0zVA 提取码:nhd9 先安装TortoiseSVN-1.7.12.24070-x64-svn-1.7. ...
- 如何使用async和await这对组合设计统一的取Access Token的函数
最近我在使用SAP云平台的机器学习API做和SAP系统的集成,因为SAP Cloud Platform Leonardo上的机器学期API,每次消费时需要传一个Access Token,故在每次实际调 ...
- awk初级教程
参考:sed & awk 概述 sed & awk指令组成 与sed区别 尽管awk指令与sed指令的结构相同,都由模式和过程两部分组成,但过程本身有很大不同. awk看上去不像编辑器 ...
- 静态库 VS 动态库
如何得到库 ①先写好一堆的.c文件(.c:我们所需要的各种工具函数) ②将这些.c编译为对应的.o ③将所有的这些.o打包为一个仓库文件(静态库或者动态库) 静态库:按照静态库的方式打包 动态库:按照 ...
- SpringBoot配置HTTPS,并实现HTTP访问自动转HTTPS访问
[转]https://www.jianshu.com/p/8d4aba3b972d 推荐使用nginx配置https,因本文产生的任何问题不再做回复. 这里说一下为什么写这篇文章,因为我也是一个Spr ...
- Redis未授权访问漏洞复现及修复方案
首先,第一个复现Redis未授权访问这个漏洞是有原因的,在 2019-07-24 的某一天,我同学的服务器突然特别卡,卡到连不上的那种,通过 top,free,netstat 等命令查看后发现,CPU ...
- 从OkHttp的源码来看 HTTP
先来了解一下OkHttp的历史,最早是square公司觉得Android给的HttpClient这块的库不太好用,于是乎做了一层包装,再后来他们包装的这个库被Android官方给收回去了,而Andro ...
- k8s的pod的资源调度
1.常用的预选策略 2.优选函数 3.节点亲和调度 3.1.节点硬亲和性 3.2.节点软亲和性 4.Pod资源亲和调度 4.1.Pod硬亲和度 4.2.Pod软亲和度 4.3.Pod反亲和度 5.污点 ...
- P1351 联合权值[鬼畜解法]
题目描述 无向连通图 G 有 n 个点,n−1 条边.点从 1 到 n 依次编号,编号为 i 的点的权值为 Wi,每条边的长度均为 1.图上两点 (u,v) 的距离定义为 u 点到 v 点的最短距离 ...
- Git报错:Your branch is up to date with 'origin/master'.
Git在提交的时候报错 Your branch is up to date with 'origin/master'. 报错 Your branch is up to date with 'origi ...