代码先锋网 代码片段及技术文章聚合

lua luaL_ref引用

 

lua luaL_ref引用

标签: lualuaL-ref
2016-04-05 13:45 1767人阅读 评论(0) 收藏 举报
 分类:

目录(?)[+]

介绍

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

下面看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 */
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

示例

可以用一个简单的例子来演示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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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

版权声明:本文为boshuzhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/boshuzhang/article/details/77527350

智能推荐

Lua table之弱引用

Lua采用了基于垃圾收集的内存管理机制,因此对于程序员来说,在很多时候内存问题都将不再困扰他们。然而任何垃圾收集器都不是万能的,在有些特殊情况下,垃圾收集器是无法准确的判断是否应该将当前对象清理。这样就极有可能导致很多垃圾对象无法被释放。为了解决这一问题,就需要Lua的开发者予以一定程度上的配合。比如,当某个table对象被存放在容器中,而容器的外部不再有任何变量引用该对象,对于这样的对象,Lua...

Lua表的引用特征

Lua表的引用特征、Lua表的赋值、Lua表的移除 分析,建立一张table_a表,并向其中插入‘A’、‘B’、‘C’三个字符,将table_a赋值给table_b,再向table_b插入字符’D’,紧接着向table_a插入字符’E’,把table_a表移除,打印出table_...

lua中的弱引用

Lua是具备自动内存管理的我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象。问题就出现在,什么对象才是垃圾对象,有些时候,我们很清楚某个对象是垃圾,但是,Lua却无法发现。 例子: 首先以一个table,叫做t。然后创建一个新的table——key1,这个key1作为t的key值,给t新增了一个字段,赋值为...

Lua笔记之弱引用

简述 一个table可以通过元表的__mode字段设置成弱引用模式,一般来说由三个模式: key是弱引用 value是弱引用 key和value都是弱引用   作用 Lua采用垃圾自动回收的内存管理机制,但有时候Lua并不能正确判断对象是否需要被销毁,导致某些需要被销毁的对象一直存在,造成内存泄漏。 如下代码Test.lua, 输出为, 程序本身的意料是,但key第二次被赋值为{}时,a...

Lua 表的弱引用

       最近被问到一个问题,什么是lua表的弱引用,之前看过lua程序设计第四版,但是当时不记得了,并不能回答出来。之后做了简单查阅,作此记录。        lua的垃圾回收机制是,当一个变量不再被引用了。当触发垃圾回收机制的时候,会回收这部分内存。而弱引用,则是更好的回收内存的一种方法。下面上代码: &nbs...

猜你喜欢

Lua

Lua 简介 Lua是脚本型语言 动态编译 动态执行 每次修改不需要重新编译链接执行 运行时编译而并非运行前编译 是C语言编写的 速度比C语言快 特性 Lua的Hello World Lua行末不要分号 Lua的括号 Lua语言几乎用不到大括号,取而代之的是do…end Lua的注释 小心不要变成纯文本了 数据类型 Lua是动态类型,不需要定义就可以直接使用 Lua的数据类型是动态可...

lua

摘要 参考 Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。 方括号 "[[]]" 来表示"一块"字符串 table 类似python中的字典...

lua

ubuntu安装lua 下载安装lua下载 在执行make时可能会报readline什么的错误 直接运行lua,可以查看是否安装成功 语法 注释 单行注释: – 多行注释: --[[ 多行注释 多行注释 –]] lua保留关键字 and break do else elseif end false for function if in local nil not or re...

Lua

Lua 特性 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。 其它特性: 支持面向过程(procedure-oriented)编程和函数式编程(functional programming); 自动内存管...

LUA

lua5.2后, 官方建议大家放弃module/package机制, 这套机制对于使用者来说是方便的, 对于module的编写者简直要抓狂, 所有module后的函数对_G均不可见, 还要一个个手动在module前转成local调用. 相当反人类. 官方建议大家手动实现package机制. 本博客之前有实现过, 参考http://www.cppblog.com/sunicdavy/archive/...