为 lua 封装 C 对象的生存期管理问题

本文探讨了在Lua中封装C对象的方法,重点讨论了生命期管理问题,并提出了三种解决方案,包括利用Lua的userdata和lightuserdata特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     原文地址: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 中管理)不满足时,还需要考虑更多细节,这里不再赘述了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值