转载自: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 对象的生存期管理问题相关推荐

  1. [zz]为 Lua 绑定 C/C++ 对象

    转载自: http://blog.codingnow.com/2013/01/binding_c_object_for_lua.html 如何绑定 C/C++ 对象到 Lua 里?通常是创建一个 us ...

  2. Lua封装C++实践(三)——Lua注册C++构造函数

    一个std::tuple<int,float,std::string>这样的结构,如何传递给int call(int,float ,std::string)这样的函数作为参数?如何根据函数 ...

  3. Lua封装C++实践(一)——Lua和C/C++的基本交互

    Lua 是一个小巧的脚本语言,它本身就是作为嵌入脚本而设计的,在目前所有脚本引擎中,Lua的速度是最快的.而且它的解释器非常轻量,其解释器不过200k(不同版本可能略有差异). Lua项目包含许多技术 ...

  4. rest_framework07:权限/频率/过滤组件/排序/异常处理封装Response对象

    权限 写一个类,继承BasePermission,如果通过返回True,否则False 这里需要配合认证使用,否则没有user_type属性. from rest_framework.permissi ...

  5. hibernate将本地SQL查询结果封装成对象

    hibernate将本地SQL查询结果封装成对象 不知道大家有没有碰过这种情况,迫于很多情况只能用native SQL来查询(如:复杂统计等),然而使用native查询后,结果会被放到object里, ...

  6. mybatis多对一,一对一,多对多resultMap映射,pojo映射,传参集合,封装的对象传参

    普通映射: <!-- 使用resultMap解决列名和属性名不一致的情况 --><!-- 配置一个resultMap映射列和属性 --><resultMap type=& ...

  7. LuaForUnity7.1:Lua“类与对象”

    前文:https://blog.csdn.net/Jaihk662/article/details/95452907(Lua表与元表) 一.Lua的"面对对象" 可以看到题目和标题 ...

  8. Spring MVC框架在进行表单提交,自动封装成对象提交,在以对象的形式入参

    最近做了一个超市订单管理系统的项目,使用的是Spring MVC 和Spring 框架. 如上图:进行新用户添加.此处jsp页面代码如下: <div class="right" ...

  9. ALIAS_TO_ENTITY_MAP 封装成对象

    ALIAS_TO_ENTITY_MAP   封装成对象 protected List<?> executeSQLMapQuery(String sql, Object param, int ...

最新文章

  1. 离散数学 关系和有向图
  2. Android自定义控件_View的绘制流程
  3. mysql之DDL操作--数据库
  4. 内存溢出和内存泄漏的区别、产生原因以及解决方案 转
  5. 【收藏】spring boot+websocket+echarts 后台推送数据用echarts展示
  6. web developer tips (28):CSS class 也支持“转到定义”
  7. 采购光纤收发器时应该注意哪些事项?
  8. 局域网聊天程序 java MySQL_课内资源 - 基于JAVA的局域网聊天软件的设计与实现(仿制QQ)...
  9. Unix中$$、$@、$#、$*的意思
  10. php电子面单打印快递100,使用快递100软件打印电子面单设置操作教程
  11. cmd强制删除文件夹
  12. sai钢笔图层的线条如何镜像复制
  13. 计算机出现假桌面怎么解决办法,W10电脑下“AppHangXProcB1”导致桌面频繁假死如何解决?...
  14. 如何恢复RAW格式移动硬盘的数据
  15. 【寒江雪】SSL通信详解
  16. python分析数据走势图_python数据分析-11数据分析实战案例
  17. 自制windows免安装版jdk
  18. Git如何上传代码到远程仓库(GiteeGithub)
  19. 数学建模的基本办法和步骤 ##数模学习1
  20. MySQL中Count和Sum的区别

热门文章

  1. webpack学习之路(四)webpack-hot-middleware实现热更新
  2. 针对ie9写特殊的样式
  3. 计算二叉树叶子节点的数目
  4. DDoS deflate–简单解决VPS被DDOS/CC攻击
  5. iOS中的图像处理(一)——基础滤镜
  6. Rake::TestTask 介绍
  7. Mysql,ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'
  8. 在线富文本编辑器FckEditor配置(.Net Framework 3.5)
  9. Java数组与容器类分析资料--数组、List和Set、Map等
  10. intellij手动添加依赖jar包