lua luaL_ref引用

来源:互联网 发布:美国官方语言 知乎 编辑:程序博客网 时间:2024/06/11 20:37

介绍

int luaL_ref (lua_State *L, int t);
Creates and returns a reference, in the table at index t, for the object at the top of the stack (and pops the object)….
You can retrieve an object referred by reference r by calling lua_rawgeti(L, t, r). Function luaL_unref frees a reference and its associated object.
在当前栈索引t处的元素是一个table, 在该table中创建一个对象, 对象是当前栈顶的元素, 并返回创建对象在表中的索引值, 之后会pop栈顶的对象; (即将栈顶元素放到t对应的table中)

源码

freelist是值为0的宏, 所以可以任务总是将t的第0个值存放了下一个空闲位置的坐标;
空闲位置通过相互连接得到一个freelist: ref = t[freelist] 存放的是上一个之前被unref的元素的位置, 而 t[ref] 则是存放上上个unref的元素位置, 这样的连接方式就形成了freelist, 以便快速查找;

LUALIB_API int luaL_ref (lua_State *L, int t) {  int ref;  if (lua_isnil(L, -1)) {    lua_pop(L, 1);  /* remove from stack */    return LUA_REFNIL;  /* 'nil' has a unique fixed reference */  }  t = lua_absindex(L, t);  lua_rawgeti(L, t, freelist);  /* get first free element   当前freelist保存了一个空闲元素位置 */  ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist]   */      lua_pop(L, 1);  /* remove it from stack */    //下面两步就是将当前freelist指向的ref位置的元素从freelist中删除,     //  同时将上上个被unref的元素位置放到freelist中;    lua_rawgeti(L, t, ref);  /* remove it from list         t[ref] 存放的是上上个被unref的元素 */         lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */  }  else  /* no free elements */    ref = (int)lua_rawlen(L, t) + 1;  /* get a new reference */  lua_rawseti(L, t, ref);   // 将栈顶元素设置到t[ref]  return ref;}

下面看unref的函数源码:

LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {  if (ref >= 0) {    t = lua_absindex(L, t);    lua_rawgeti(L, t, freelist);    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist]   类似将unref的位置插入链表头 */       lua_pushinteger(L, ref);    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */  }}

示例

可以用一个简单的例子来演示luaL_ref的用法:

// main.lua中有个全局函数function gf()  print("hello world")end// c++中处理void callgf(){  lua_getglobal(L,"gf");  // 存放函数到注册表中并返回引用  int ref =  luaL_ref(L,LUA_REGISTRYINDEX);  // 从注册表中读取该函数并调用  lua_rawgeti(L,LUA_REGISTRYINDEX,ref);  lua_pcall(L,0,0,0);}

上面的函数会调用gf打印出”hello world”

1 0
原创粉丝点击