您的位置:首页 > 编程语言 > Lua

lua luaL_ref引用

2016-04-05 13:45 513 查看

介绍

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”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lua luaL-ref