关于lua中userdata的理解

@[TOC] 关于lua中userdata的理解

关于Userdata的理解

Userdata数据结构

  • userdata是用来存放用户自定义数据结构的实列,userdata的类型有两种类型,分别是lightuserdata,和fulluserdata。lightuserdata是value结构中的一个变量类型,本质上是一个void*指针:
// luaobject.h 
   typedef union lua_Value{
   
     struct GCObject* gc;
     void* p;
     int b;
     lua_Integer i;
     lua_Number n;
     lua_CFunction f;
  }  Value;

light userdata的内存,需要用户自行管理,而fulldata则是通过lua的gc机制进行管理,本章主要讲fulluserdata,所有的userdata均为full userdata。
对full userdata的操作实现,一般在C层进行的,后面会有例子
userdata的数据结,在dummylua中,定义如下所示:

//luaobject.h
#define CommonHeader struct GCObject* next ;lua_byte tt_ ;lu_byte marked
typedef struct Udata {
   
    CommonHeader;    //GC公共头部
    struct Table* metatable; //userdata 可以设置metatable,一般用于设置_gc域,在userdata被回收之前,
                                                //__gc函数会被调用,一般用于回收系统资源
    int ttuv_;                               //相当于Tvalue 的tt_,用来指代user_变量的类型
    int len;                              // 自定义域的大小
    Value user_;                       //本质就是Tvalue的value_的value部分,这里将TValue拆分成了两个部分
}Udata;

UserData的接口

分别是Lua_newuserdata.getudatamem,setuservalue.getuservalue。
luaS_newuserdata的定义:

//luastring.c
udata*  luaS_newuserdata(struct lua_State* L,int size);

这个接口,就是创建了一个userdata实例,这个userdata实例的大小就是Udata头部+传入的size大小,我们可以看一下实例的构成:
±-------------------±------------------+
|Header:Udata | user domain |
±-------------------±-----------------+
前面的Header,就是sizeof(Udata)的大小,而后面的user domain,则是luaS_newuserdata的第二个参数size来指定,比方,现在我们定义了一个Vector3的数据结构:

    typedef struct Vector3 {
   
          float x;
          float y;
          float  z;
    }Vector3;
要创建时,这个Vector3 关联的userdata。那么它的创建代码则如下所示:
   Udata* u = luaS_newuserdata(L,sizeof(Vector3));

第二个参数,size的大小则是sizeof(vector3)的大小,也就是12,那么此时,user domain的大小则为12byte的大小。
在完成了userdata实例的创建之后,要在C层获取我们自定义的结构实例的指针,此时需要一个接口getudatamem.

     #define getudatamem(o) (cast(char*,o)+sizeof(Udata))

这个宏的作用在。则是将userdata实例中,user domain部分的指针拿到,获取的结果所指向的位置,如下’ ^ '所示:
±-------------------±------------------+
|Header:Udata | user domain |
±-------------------±-----------------+
^
通过这个宏,我们可以获取结构自定义结构变量的实例,具体方法如下所示:

  Vector3* v3 = (vector3*)getudatamem(u);

接下来,就可以对V3所指向的内存块进行对应的处理了.
userdata 还有一个重要的接口,就是setuserdata,这是一个宏,它的作用是将一个Tvalue实例赋值到Udata头部中,分别将TValue实例的tt__赋值给Udata的ttuv_,将TValue的value_赋值给Udata的user_字段中,其定义如下所示:

//luaobject.h
#define setuservalue(u ,o)\
              (u) ->ttuv_ = (O) ->tt_;(u) ->user_=(o)->value_
luaobject.h
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值