C语言结构体占用内存存储于Udata结构体的末尾,Udata有两种使用形式:一种声明了UValue数组,可以额外存储一组数据,另一种则没有声明,而是直接后面就接上C语言结构体(结构相当于上图中的Udata0结构体),内存结构分别如下图所示,左边红色部分为使用UValue数组所多出来的部分:
Udata的创建代码见源码《lstring.c》luaS_newudata:
Lua源码中提供了设置与获取UValue数组元素的set与get函数,不用细看:
源码《lapi.c》lua_setiuservalue:
源码《lapi.c》lua_getiuservalue:
在极大多数情况下,使用Udata都不需要用到UValue数组,因为C语言结构体也存在于Udata之中(末尾),在这个结构体中完全可以存储所需要的任何数据,不需要非得存储在UValue数组当中,所以我们可以不需要学习这一种Udata的使用方式。可以把Udata直接理解为下图的Udata0来使用:
Udata0仅在计算Udata占用内存空间大小的时候会用于计算,实际源码中不会真正创建出Udata0类型的对象,上图中的bindata即可理解为指向C语言结构体的指针,调用luaS_newudata在C语言中创建一个userdata后,bindata这部分数据在栈顶,C语言中可直接对这部分内存强制转换为对应的C语言结构体对象,如开篇中的例子:
pPeople = (struct People *)lua_newuserdata(L, sizeof(struct People));
知道了怎么创建一个UserData以及其内部结构。我们接下来看下删除是怎么实现的。
UserData的删除
非常简单,userdata的删除也跟其它Lua基础类型一样,当没有被引用的时候就会被清除,在C语言中不需要手动管理这部分内存,这里的引用指的是在Lua中的使用,在C语言中调用时并不算引用。Lua的标记清除垃圾回收机制能正常检测到无引用的userdata并得以清除。
UserData需要元表的配合才完整
现在我们来扩展我们的例子,在Lua中创建了UserData之后,我们C语言中尝试获取这个UserData对应的People结构体,并修改它的name字段为"MaNong":
获取UserData可以使用如下lua_touserdata方法:
本文地址:百科问答频道 https://www.neebe.cn/wenda/935433_2.html,易企推百科一个免费的知识分享平台,本站部分文章来网络分享,本着互联网分享的精神,如有涉及到您的权益,请联系我们删除,谢谢!