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);

最新文章

  1. MySQL:常见使用问题
  2. SharePoint2007:解决第二回收站大数据无法删除问题
  3. qt 焦点设置策略
  4. hdu5179(数位dp)
  5. Java程序猿JavaScript学习笔记(14——扩大jQuery UI)
  6. C#笔记(二)变量
  7. H5页面适配所有iPhone和安卓机型的六个技巧
  8. 怎么在linux Ubuntu上部署nodejs
  9. C#中判断语句 if、if-else if、switch-case
  10. [国嵌攻略][052][NandFlash驱动设计_读]
  11. app.config的坑
  12. 初步了解.net
  13. 【Spark调优】数据倾斜及排查
  14. sqlserver text类型字段错误 net.sourceforge.jtds.jdbc.ClobImpl@66fa192的解决方法
  15. list-循环小练习(作业已交未交)
  16. Python3 系列之 环境配置篇
  17. 洛谷 P1417烹调方案
  18. swoole Tcp
  19. Python 基础语法+简单地爬取百度贴吧内容
  20. angular中的jqLite所包含的jquery API

热门文章

  1. React Native 开发豆瓣评分(一)环境搭建&amp;配置模拟器
  2. ubuntu下使用JNI Java调用C++的例子
  3. Fatal error:Call to undefined function mysqli_connect() in .php line 报错
  4. BLE 广播格式定义
  5. [LeetCode] 148. 排序链表 ☆☆☆(归并排序)
  6. MySQL增删查改语句(入门)
  7. Linux 命令之 alias
  8. Activity之launchMode理解
  9. 搭建Git服务器环境----Git hooks代码自动部署
  10. ubuntu下新立得(synaptic)软件包管理器安装