[zz]为 lua 封装 C 对象的生存期管理问题
转载自:http://blog.codingnow.com/2009/03/lua_c_wrapper.html
把 C 里的对象封装到 lua 中,方便 lua 程序调用,是很常见的一项工作。
里面最大的问题是生命期管理问题。
通常有两种方案:
第一:编写 C 库的时候,完全针对 lua 设计,所有对象都有 lua_newuserdata
分配内存。对象和对象之间的联系可以使用 userdata 的 环境表,把对象间的引用放在里面,使得 lua 的 gc 过程可以正常进行。
第二:给 C 对象简单加一个壳。lua 的 userdata 中仅仅保存 C 对象指针。然后给 userdata 设置 gc 元方法,在被回收时,正确调用 C 对象的销毁函数。
以上两种方案都依赖 lua 的 full userdata ,这里,我想提供第三种方案,仅使用 lightuserdata 完成这项工作。
这第三方案未必比前两种都好。虽然从字面上理解 light userdata 比 full userdata 更廉价,但诚如 pil 中所言,full userdata 也非过于重量。
最终的方案选择还是要结合实际的设计,仔细考量。
方法很简单:
如果你可以保证,所有对象用户只从 lua 层面创建,并依赖 lua 层的 gc 机制销毁。那么仅需要在 lua 中维护一张弱表,把每个创建出来的 lua 封装对象(一般是一个 table)放在这张表中(其实是一个集合)。
同时,在 C 中也维护一个集合(一个简单的对象指针数组即可)。每次对象创建,便把 C 对象指针放入集合。
这样, C 里的集合引用的对象一定是 lua 中那个集合的超集。下面,仅需要周期性的对比两个集合,把 C 集合中多余的对象销毁掉即可。
真正使用时,尤其是前面提到的前提(所有对象只能从 lua 中管理)不满足时,还需要考虑更多细节,这里不再赘述了。
3 月 14 日 补充:
可以通过向 lua 的对象集合(一个弱表)中放置一个 C 收集器来实现在 lua gc 后自动回收 C 对象。这个 C 收集器实现简单,用一个 userdata 绑定一个 gc 元方法即可。
需要注意的是,创建 C 对象和创建 lua 对象,并将两者绑定需要是一个原子操作。否则中间可能被 gc 打断,导致 C 对象被提前回收。
[zz]为 lua 封装 C 对象的生存期管理问题相关推荐
- [zz]为 Lua 绑定 C/C++ 对象
转载自: http://blog.codingnow.com/2013/01/binding_c_object_for_lua.html 如何绑定 C/C++ 对象到 Lua 里?通常是创建一个 us ...
- Lua封装C++实践(三)——Lua注册C++构造函数
一个std::tuple<int,float,std::string>这样的结构,如何传递给int call(int,float ,std::string)这样的函数作为参数?如何根据函数 ...
- Lua封装C++实践(一)——Lua和C/C++的基本交互
Lua 是一个小巧的脚本语言,它本身就是作为嵌入脚本而设计的,在目前所有脚本引擎中,Lua的速度是最快的.而且它的解释器非常轻量,其解释器不过200k(不同版本可能略有差异). Lua项目包含许多技术 ...
- rest_framework07:权限/频率/过滤组件/排序/异常处理封装Response对象
权限 写一个类,继承BasePermission,如果通过返回True,否则False 这里需要配合认证使用,否则没有user_type属性. from rest_framework.permissi ...
- hibernate将本地SQL查询结果封装成对象
hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...
- mybatis多对一,一对一,多对多resultMap映射,pojo映射,传参集合,封装的对象传参
普通映射: <!-- 使用resultMap解决列名和属性名不一致的情况 --><!-- 配置一个resultMap映射列和属性 --><resultMap type=& ...
- LuaForUnity7.1:Lua“类与对象”
前文:https://blog.csdn.net/Jaihk662/article/details/95452907(Lua表与元表) 一.Lua的"面对对象" 可以看到题目和标题 ...
- Spring MVC框架在进行表单提交,自动封装成对象提交,在以对象的形式入参
最近做了一个超市订单管理系统的项目,使用的是Spring MVC 和Spring 框架. 如上图:进行新用户添加.此处jsp页面代码如下: <div class="right" ...
- ALIAS_TO_ENTITY_MAP 封装成对象
ALIAS_TO_ENTITY_MAP 封装成对象 protected List<?> executeSQLMapQuery(String sql, Object param, int ...
最新文章
- 离散数学 关系和有向图
- Android自定义控件_View的绘制流程
- mysql之DDL操作--数据库
- 内存溢出和内存泄漏的区别、产生原因以及解决方案 转
- 【收藏】spring boot+websocket+echarts 后台推送数据用echarts展示
- web developer tips (28):CSS class 也支持“转到定义”
- 采购光纤收发器时应该注意哪些事项?
- 局域网聊天程序 java MySQL_课内资源 - 基于JAVA的局域网聊天软件的设计与实现(仿制QQ)...
- Unix中$$、$@、$#、$*的意思
- php电子面单打印快递100,使用快递100软件打印电子面单设置操作教程
- cmd强制删除文件夹
- sai钢笔图层的线条如何镜像复制
- 计算机出现假桌面怎么解决办法,W10电脑下“AppHangXProcB1”导致桌面频繁假死如何解决?...
- 如何恢复RAW格式移动硬盘的数据
- 【寒江雪】SSL通信详解
- python分析数据走势图_python数据分析-11数据分析实战案例
- 自制windows免安装版jdk
- Git如何上传代码到远程仓库(GiteeGithub)
- 数学建模的基本办法和步骤 ##数模学习1
- MySQL中Count和Sum的区别
热门文章
- webpack学习之路(四)webpack-hot-middleware实现热更新
- 针对ie9写特殊的样式
- 计算二叉树叶子节点的数目
- DDoS deflate–简单解决VPS被DDOS/CC攻击
- iOS中的图像处理(一)——基础滤镜
- Rake::TestTask 介绍
- Mysql,ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'
- 在线富文本编辑器FckEditor配置(.Net Framework 3.5)
- Java数组与容器类分析资料--数组、List和Set、Map等
- intellij手动添加依赖jar包