项目正在使用cocos2dx的lua绑定,绑定的方式是tolua++。对大规模使用lua代码信心不是很足,花了一些时间阅读tolua++的代码,希望对绑定实现的了解,有助于项目对lua代码的把控。从阅读结果上来看,起码在内存管理上,帮助还是很大的。

1.tolua++如何将c++对象导入到lua里

tolua++为每一个传入lua的对象建立一个userdata,userdata的值,是c++对象的地址。userdata的metatable,是一个tolua++建立的,记录了userdata对应c++类型信息的表格,包括导出的成员变量、成员函数等信息。

对于成员变量的读取赋值,tolua++是在metatable里新建了.get和.set两个表。两个表里分别存储了以变量名为键,以读取设置c函数为值的表项。在metatable的__index和__newindex里,以变量名为键,从.get和.set表里取得读取设置函数并调用。

对于成员函数的调用,只需要以函数名为键,函数为值,存储在metatable里就好了。

传入c++对象的tolua++函数是tolua_pushusertype。一般情况下,第一次使用这个函数将一个c++对象push到lua堆栈上时,才会新建userdata。tolua++会以c++对象地址为键,userdata为值,将键值对存储在tolua_ubox表里。下次推入同样的c++对象时,从这个表里取出userdata推入堆栈即可。

—————————————————

2.tolua++如何处理类型的继承

父类的metatable,是子类metatable的metatable。这样调用父类方法时,就会去父类的metatable里查找了。

tolua++还维护了一个tolua_super表,这个表以c++类型的metatable为键,以一个表格为值。这个值表格以类型名称为键,以true为值,记录了metatable对应c++类型的父类有哪些。这个表格可以用来帮助判断对象是否是某一个类型(子类实例也可以认为是父类类型)

—————————————————

3.tolua++如何管理对象的生命周期

一般情况下,当lua里对c++对象的引用变量可以被垃圾回收时,tolua++只是简单的释放userdata占用的4字节指针地址内存。但是也可以通过绑定或者代码指定的方式,让tolua++真正释放对象所占内存。

绑定的方式,是指在将c++类型构造函数使用tolua++导出到lua里时,tolua++会自动生成new_local方法。如果在lua代码里,用这个方法新建对象时,tolua++会调用tolua_register_gc方法,指明回收对象时回收对象内存。

在c++代码里,使用tolua_pushusertype_and_takeownership;在lua代码里,使用tolua.takeownership,都可以达到同样的目的。

对于这些指定由tolua++回收内存的对象,如果其类型的析构函数也通过tolua++导出了,则在回收内存时,会通过delete运算符,调用对象的析构函数。否则只会使用free方法回收。

tolua_register_gc方法,做的事情,是以对象指针为键,以对象metatable为值,将键值对存储在tolua_gc表里。在对象类型的metatable表的__gc方法里,tolua++会检查tolua_gc表是否包含以这个地址为键的表项。包含的话才会进行上述的内存回收工作。

4.其它

有的时候,在lua里取得一个c++对象后,我们想赋给它一些只在lua环境下有意义的属性。或者,我们想在lua里扩展一个c++类。tolua++也提供了实现这种需求的机制。

tolua++在LUA_REGISTRY里维护了一张tolua_peers表。这张表以表示c++对象的userdata为键,以一张表格t为值。t里面就记录了这个对象在lua里扩展的属性。

cocos2dx并没有完全使用tolua++的方式,而是自己进行了一些修正。下篇博客应该会记录修正的原因和方式,并介绍一些cocos2dx lua bind特定的东西。

tolua++实现分析的更多相关文章

  1. cocos2dx之tolua++全面分析(一):tolua++工具本身

    在cocos2dx/tools/tolua++下面,有大量pkg文件,这些是按tolua++要求格式写好的.需要导出到lua中的c++类描述文件. 每当在c++类里增加了新函数需要导出时,应同步修改相 ...

  2. cocos2dx之tolua++全面分析(二):类注册

    tolua被作为库使用时,首先会做大量内部初始化工作: 一.tolua_open是入口点,它创建很多用于管理的内部变量,以下用_G指代全局表,_R指定registry table: 1._R.TOLU ...

  3. tolua++实现lua层调用c++技术分析

    tolua++技术分析 cocos2dx+lua 前言 一直都使用 cocos2dx + lua 进行游戏开发,用 Lua 开发可以专注于游戏逻辑的实现,另外一方面可以实现热更新:而且 lua 是一个 ...

  4. luac++

    Cocos2d-x下Lua调用自定义C++类和函数的最佳实践 洪亮 305 2014年08月09日 发布   1 推荐 21 收藏,14.9k 浏览 关于cocos2d-x下Lua调用C++的文档看了 ...

  5. cocos2dx的lua绑定

    一.cocos2dx对tolua++绑定的修正 A.c对lua回调函数的引用 在使用cocos2dx编写游戏时,我们经常会设置一些回调函数(时钟.菜单选择等).如果采用脚本方式编写游戏的话,这些回调函 ...

  6. 【转】Cocos2d-x下Lua调用自定义C++类和函数的最佳实践

    转自:http://segmentfault.com/blog/hongliang/1190000000631630 关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明 ...

  7. cocos2dx tolua传递参数分析

    cocos2dx tolua传递参数分析: tolua_Cocos2d_CCNode_addChild00 == void CCNode::addChild(CCNode *child) tolua_ ...

  8. tolua#代码简要分析

    简介 tolua#是Unity静态绑定lua的一个解决方案,它通过C#提供的反射信息分析代码并生成包装的类.它是一个用来简化在C#中集成lua的插件,可以自动生成用于在lua中访问Unity的绑定代码 ...

  9. cocos2dx 3.x tolua 分析

    cocos2dx 3.x 版本已经出到3.10了,终于决定要进行引擎版本升级,c++配合lua进行游戏开发,从3.x版本开始cocos使用了新的tolua方式,由于不懂python,折腾tolua搞的 ...

随机推荐

  1. nginx做反向代理并防盗链

    nginx做反向代理真的非常简单,只需设置location+proxy_pass即可. 防盗链配置有些复杂,需要注意的地方: 在防盗链的location中需要再设置一下proxy_pass(在这里走了 ...

  2. How Delete File with Readonly Permission?

    class Program { static void Main(string[] args) { string file=@"E:\readme.txt"; try { File ...

  3. Ubuntu上安装ns2-2.34

    Ubuntu上安装ns2-2.34 步骤1 下载ns-allinone-2.34 $ tar zxf ns-allinone-2.34.tar.gz 步骤2 sudo apt-get install ...

  4. Server Develop (五) Linux并发模型

    Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模 ...

  5. hibernate 一对一关联关系 及其懒加载,总结

    一对一,则有主对象和从对象之区别 若无主对象,则从对象亦无存在之意义. 主对象为person 从对象为idcard <hibernate-mapping package="cn.itc ...

  6. 隐藏路由器的WIFI信号,防蹭网

    进入路由器的管理界面 最后别忘了 现在信号隐藏了,现在说一下如何用手机连接隐藏的路由器

  7. MyEclipse8.6中提交SVN报错

    上周五(11月27日)的时候,从TortoiseSVN提交项目报错,然后直接从MyEclipse中检出来,修改后提交同样报错. MyEclipse8.6中提交SVN报错,错误提示如下: commit ...

  8. js异步加载的三种解决方案

    默认情况javascript是同步加载的,也就是javascript的加载时阻塞的,后面的元素要等待javascript加载完毕后才能进行再加载,对于一些意义不是很大的javascript,如果放在页 ...

  9. Windows下提升进程权限

    windows的每个用户登录系统后,系统会产生一个访问令牌(access token) ,其中关联了当前用户的权限信息,用户登录后创建的每一个进程都含有用户access token的拷贝,当进程试图执 ...

  10. 我所理解的JavaScript闭包

    目录 一.闭包(Closure) 1.1.什么是闭包? 1.2.为什么要用闭包(作用)? 1.2.1.保护函数内的变量安全. 1.2.2.通过访问外部变量,一个闭包可以暂时保存这些变量的上下文环境,当 ...