前言

上一篇博客记录了 tolua++ 将 c++类型,变量,函数,以及对象导出到 lua 的过程,这篇博客就接着记录一下 c++对象的内存回收以及c++对象数据和方法在lua中的扩展。


  1. 首先 tolua_reg_types() 在为 c++ 类型创建元表的时候,会在元表中创建一个key-value : __gc = tolua_gc_event

  2. 然后在 tolua_cclass ( ... , lua_CFunction col) 的过程中,会传入一个 c++ 对象的析构函数 , 以 .collector为key, 以析构函数为value 创建一个键值对放置于 c++ 类型元表中,即 type.mt.collector = col

  3. tolua++ 会为 c++对象的构造函数 创建相应的 new_local 方法,在 lua 层调用 new_local 的时候, 会触发 tolua_register_gc 即以c++指针为键,c++类型对应的元表为值,将这对key-value放于_R.tolua_gc中。

  4. 最后 lua 在垃圾回收的过程中,会触发 class_gc_event (lua_State* L) 来处理一个要被回收的 c++对象(userdata)。

    1. 首先检查 _R.tolua_gc 中是否有 以该userdata为key,以userdata的元表为value的键值对存在。
    2. 如果键值对存在于tolua_gc表中,就会在userdata的元表中取出.collector所对应的析构方法并且执行。
    3. 最后再以 _R.tolua_gc.userdata = nil 的方式将键值对移除gc表。这样就可以实现在lua中析构掉c++对象的内存。

lua扩展c++对象

Lua5.1

在lua 5.1中有 tolua.getpeer tolua.setpeer 两个方法可以在lua扩展c++对象。因为在lua中可以创建多个c++对象的实例,多个实例共享同一个c++类型所对应元表的里面设置的方法,但是多个实例的数据成员是相互独立,所以 tolua 就弄了一个peer表来存储c++在lua中的新增方法和数据。那么getpeer 和 setpeer方法就可以对这个peer表存取访问。

1 setpeer 一般用法: tolua.setpeer(c++_object,lua_table) 即将lua_table设置为c++_object的peer表 ,之后对实例对象进行get/set操作的时候首先会去遍历这个lua_table,然后再去遍历c++类对应的元表;那么这个lua_table中的数据和方法就属于当前实例对象自身的,与同一个c++类的其他实例无关。

2 getpeer 一般用法: tolua.getpeer(c++_object) 获取c++_object的peer表。

Lua低版本

lua版本小于5.1 ,是没有tolua.getpeer tolua.setpeer两个方法的, 低版本在lua中扩展c++对象的方式如下:

1 在注册表中准备一张 tolua_peers 的表 , 这张表以userdata为键,以c++对象在lua中新增的成员变量和方法的集合为值。

2 之后对实例对象进行get/set操作的时候会从tolua_peers表中找出userdata对应的成员变量与方法的集合,再从集合中寻找对应的成员变量或方法。

c++对象在lua层的生命周期与内容扩展的更多相关文章

  1. Java对象在JVM中的生命周期

          当你通过new语句创建一个java对象时,JVM就会为这个对象分配一块内存空间,只要这个对象被引用变量引用了,那么这个对象就会一直驻留在内存中,否则,它就会结束生命周期,JVM会在合适的时 ...

  2. JAVA-JSP内置对象之session对象设置并获得session生命周期

    相关资料:<21天学通Java Web开发> session对象设置并获得session生命周期1.通过session对象的setMaxInactiveInterval()方法可以设置se ...

  3. 《深入Java虚拟机学习笔记》- 第7章 类型的生命周期/对象在JVM中的生命周期

    一.类型生命周期的开始 如图所示 初始化时机 所有Java虚拟机实现必须在每个类或接口首次主动使用时初始化: 以下几种情形符合主动使用的要求: 当创建某个类的新实例时(或者通过在字节码中执行new指令 ...

  4. Autofac容器对象实例的几种生命周期类型

    实例范围决定了如何在同一服务的请求之间共享实例. 请注意,您应该熟悉生命周期范围的概念,以便更好地理解此处发生的情况. 当请求服务时,Autofac可以返回单个实例(单实例作用域),新实例(每个依赖作 ...

  5. spring总结之一(spring开发步骤、bean对象的管理、bean生命周期)

    ###spring 1.概念:开源,轻量级,简化开发的企业级框架. 开源:免费,发展快. 轻量级:占内存小. 简化开发:通用的功能封装,提高程序员的开发效率.--------------------- ...

  6. cocos2dx 3.x(场景(层)的生命周期)

    //进入当前层初第一步始化层调用 bool GameScence::init() { if( !void init() ) { returnfalse; } log("进入当前层初第一步始化 ...

  7. Hibernate 系列 06 - 对象在JVM中的生命周期

    引导目录: Hibernate 系列教程 目录 Java对象通过new命令进行创建,Java虚拟机(Java Virtual Machine,JVM)会为新的Java对象在内存中开辟一个新空间以存放次 ...

  8. lua关于参数生命周期的研究

    local num = 123 local str = "abc" local tb ={} 数字和字符串类型的值作为参数传递的时候,是复制值,2个独立的内存地址 table类型的 ...

  9. C#中Unity对象的注册方式与生命周期解析

    1.示例代码 请详细阅读 static void Main(string[] args) { { Console.WriteLine("----------全局设置----------&qu ...

随机推荐

  1. Linux学习(十三)du、df、fdisk磁盘分区

    一.du du命令是查看文件或者目录大小的命令. 一般使用du -sh 查看,不用-sh参数意义也不大,应为不用这个参数,它会把目录下的所有文件大小递归的显示出来,就像这样: 如果用-sh参数: [r ...

  2. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) K Tournament Wins

    题目链接:http://codeforces.com/gym/101201 /* * @Author: lyucheng * @Date: 2017-10-22 14:38:52 * @Last Mo ...

  3. A strange lift

    Problem Description There is a strange lift.The lift can stop can at every floor as you want, and th ...

  4. HDU Today

    HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  5. Android 开发笔记___初级控件之实战__计算器

    功能简单,实现并不难,对于初学者可以总和了解初级控件的基本使用. 用到的知识点如下: 线性布局 LinearLayout:整体界面是从上往下的,因此需要垂直方向的linearlayout:下面每行四个 ...

  6. Problem E: 动物爱好者

    Problem E: 动物爱好者 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 882  Solved: 699[Submit][Status][Web ...

  7. web前端学习路线和步骤

    H5+全栈工程师  (学习下列技术可以加QQ: 1416 7596 61)第一阶段:初级入门阶段基本功 1.HTML入门 Windows概述.浏览器概述.HTML简介.HTML标签详解.前端开发工具概 ...

  8. c# RSA加密和解密

    ");            Console.WriteLine(encodeString);            string decode = MyRSA.Decrypt(encode ...

  9. Python之作用域

    作用域测试例子: >>> a = 10 >>> def test(): ... a = 20 ... print a ... >>> a 10 & ...

  10. FPGA跨时钟域处理方法

    文章主要是基于学习后的总结. 1. 时钟域 假如设计中所有的触发器都使用一个全局网络,比如FPGA的主时钟输入,那么我们说这个设计只有一个时钟域.假如设计有两个输入时钟,如图1所示,一个时钟给接口1使 ...