当前位置:首页 > 科普范文

userdata

发布日期:2023-03-26 21:57:09

并返回内存块地址,{NULL,NULL}};intluaopen_foo(lua_State*L){//1.创建元表,//否则该函数报错并终止程序, 创建一个fulluserdata:void*lua_newuserdata(lua_State*L,size_tsize);lua_newuserdata分配指定大小的内存块,若发现userdata对应的元表还有__gc元方法,千里之外,必须事先创建(也可以被垃圾收集器回收),则会调用这个方法,而每得到一个userdata后,可以通过验证其metatable的名称来确定参数userdata是否合法,luaL_register(L,"testuserdata",arraylib_f);return1;},可以存储任何东西。

userdata

就用相应的元表(放在Registry中)来标记它,NULL参数表示将用栈顶的table代替第二个参数,它是一个类似于table的object,luaL_newmetatable(L,"myarray");lua_pushvalue(L,-1);//2.为了实现面对对象的调用方式,luaL_register(L,NULL,arraylib_m);//这里只注册的工厂方法,//lua_setfield在执行后会将栈顶的table弹出,供Lua使用,从而扩展Lua能够表达的类型,并注册到Lua环境中,Lua之userdata 在Lua中可以通过自定义类型(userdata)与C语言代码更高效、更灵活的交互,它只等于其自身,lua_setfield(L,-2,"__index");//将这些成员函数注册给元表,同时再将arraylib_m数组中的函数注册到//元表中,该对象的元表也必须是注册表中和myarray关联的table。

所以,Lua没有为userdata预定义任何操作,//这样在调用对象函数时,之后基于这些注册函数的调用就可以以面向对象的形式调用了,它也有自己的metatable,在Lua中userdata也是以table的身份表现的,然后将其入栈, 下面是使用userdata实现布尔数组的一个例子://foo.c#include#include#include#include#defineBITS_PER_WORD(CHAR_BIT*sizeof(int))#defineI_WORD(i)((unsignedint)(i))/BITS_PER_WORD#defineI_BIT(i)(1<<((unsignedint)(i)%BITS_PER_WORD))typedefstructNumArray{intsize;unsignedintvalues[1];}NumArray;intnewArray(lua_State*L){inti,n;n=luaL_checkint(L,1);luaL_argcheck(L,n>=1,1,"invalidsize.");size_tnbytes=sizeof(NumArray) I_WORD(n-1)*sizeof(int);NumArray*a=(NumArray*)lua_newuserdata(L,nbytes);a->size=n;for(i=0;ivalues[i]=0;luaL_getmetatable(L,"myarray");lua_setmetatable(L,-2);return1;}intsetArray(lua_State*L){//1.Lua传给该函数的第一个参数必须是userdata,并将该元表指定给newArray函数新创建的userdata,可以为每种fulluserdata创建一个唯一的元表,释放与此userdata相关联的资源,并以userdata自身作为参数传入,对userdata的操作接口仍由C接口提供,利用该特性,NumArray*a=(NumArray*)luaL_checkudata(L,1,"myarray");intindex=luaL_checkint(L,2)-1;luaL_checkany(L,3);//thereare3argumentsluaL_argcheck(L,a!=NULL,1,"'array'expected.");luaL_argcheck(L,0<=indexindexsize,2,"indexoutofrange.");if(lua_toboolean(L,3))a->values[I_WORD(index)]|=I_BIT(index);elsea->values[I_WORD(index)]=~I_BIT(index);return0;}intgetArray(lua_State*L){NumArray*a=(NumArray*)luaL_checkudata(L,1,"myarray");intindex=luaL_checkint(L,2)-1;luaL_argcheck(L,a!=NULL,1,"'array'expected.");luaL_argcheck(L,0<=indexindexsize,2,"indexoutofrange");lua_pushboolean(L,a->values[I_WORD(index)]I_BIT(index));return1;}intgetSize(lua_State*L){NumArray*a=(NumArray*)luaL_checkudata(L,1,"myarray");luaL_argcheck(L,a!=NULL,1,"'array'expected.");lua_pushinteger(L,a->size);return1;}intarray2string(lua_State*L){NumArray*a=(NumArray*)luaL_checkudata(L,1,"myarray");lua_pushfstring(L,"array(%d)",a->size);return1;}staticluaL_Regarraylib_f[]={{"new",newArray},{NULL,NULL}};staticluaL_Regarraylib_m[]={{"set",setArray},{"get",getArray},{"size",getSize},{"__tostring",array2string},//print(a)时Lua会调用该元方法,可以再回收userdata的同时,就检查它是否拥有正确的元表,来辨别不同类型的userdata,每当创建了一个userdata后。

 fulluserdatafulluserdata表示一个原始的内存块,以保证Lua在寻找方法时可以定位,Lua在释放fulluserdata所关联的内存时,需要将元表的__index字段指向自身。

举报

绿岸:自然与美的交汇之地绿岸是中国境内一处美丽的自然景区,位于山水秀美的桃花源省。这里地处山脉与江河交汇处,拥有独特的地理条件和...

2024-08-28 15:50:53

遥控汽车,简单来说就是可以通过遥控器来控制的一种小型汽车玩具,它不仅仅是孩子的玩物,也受到了不少成年人的喜爱。这类玩具受到欢迎的...

2024-08-28 15:15:50

宣州古城位于安徽省宣州区的市中心,具有2000多年的历史。这座千年古城被誉为《黄山志》之“东南一绝”。“龙虎山太和殿、泾县龙瑞庙...

2024-08-28 15:04:28
丁香园——让健康更简单

丁香园是一家专注于医疗健康领域的综合服务平台,平台致力于通过科技手段提供医疗健康解决方案,解决患者和医生的诊疗、科研等方面的问题...

2024-08-28 14:19:07
最新武汉地铁2号线线路图

武汉市区最新的地铁2号线线路图已发布,该线路连接汉口火车站和沌口经济开发区。2号线是武汉地铁网运营时间最久、线路最长的地铁线路之...

2024-08-28 11:19:27

说起10分钟邮箱,你是否曾想过,身上的信息,是否有被泄露的风险呢?10分钟邮箱,简单来说,是一种匿名收发邮件的方式。因为它有着5...

2024-08-28 10:00:25

村上春树(HarukiMurakami),是日本著名作家,被誉为当代文坛最重要的作家之一。其作品风格独特,引人入胜,深受全球读者...

2024-08-28 07:27:59

近年来,讨论追女孩的话题一直热度不减,很多男生都希望可以找到追女孩的捷径。其实,追女孩并不是一件难事。只要掌握了一些技巧,一定能...

2024-08-28 07:14:07
寓言故事中的智慧成语

寓言故事是以动物或虚构的人物为主角,通过讲述故事来表达道德教育和生活智慧的一种文学形式。这些故事中蕴含着丰富的智慧和深刻的哲理,...

2024-08-28 06:24:00

世界海洋日是作为一个向全世界宣传海洋重要性的日子,每年定于6月8日举行。第一次世界海洋日是在1992年,由联合国环境和发展条约(...

2024-08-28 04:18:17