tolua#中的userdata
2020-03-01 03:53
1161 查看
- tolua中c#和lua交互过的对象都有一个ref编号, ref是int类型,ref唯一不重复,一个ref对应一个c#对象
- tolua中任何c#对象在lua中对应的userdata都是一个int类型的内存指针地址,通过对这个userdata设置不同的metatable来区分userdata对应的c#类型
- 这个userdata指针指向的int内存的值等于第1条的ref值,比如有个c#对象的ref等于13,那么userdata指针指向的内存的值就等于13
- userdata在lua中被缓存在一个叫ubox的弱表里,userdata在ubox的下标等于c#对象对应的ref,比如有个c#对象的ref等于13,那么这个c#对象的userdata在ubox的下标就是13,如果一个userdata只被ubox指向,那么这个userdata会被GC
- tolua中一个c#对象被首次push进lua中,会申请一块内存,大小为sizeof(int),userdata就是指向这块内存的指针,并且调用lua_setfenv把userdata的环境表设置为TOLUA_NOPEER,调用lua_setmetatable把userdata的元表设置为c#对象在lua中特定的一个table(每个被bind的c#对象都会有一个对应的meta表,这个meta表存放着c#对象对应的方法的指针)
- tolua Bind注册一个c#类,假设这个c#类叫A类,会创建一个对应的metatable,我们叫这个metatable为mtA,A类的wrap文件的static方法会对应的赋值给mtA。当tolua要push一个A类到lua是,会创建一个userdata,并且设置userdata的metatable为mtA。mtA的__index元方法等于一个叫class_index_event的luacfunction。因为userdata什么都没有,所以访问userdata的成员的时候,会调用class_index_event,class_index_event的访问规则如第7条。
- 访问一个userdata成员,比如userdata.name,会进行如下步骤:先直接在userdata的环境表peer找,value = rawget(peer, name),value不为nil则直接否则返回value赋值给userdata.name,下面的步骤都不用执行了。value为nil则进行第2步。
- 在peer的gettable找,gettable = peer[&gettag],如果rawget(gettable, name)是一个function(luafunction或者cfunction)则call这个function,function的返回值赋值给userdata.name。否则,进行第3步。
- 如果peer有元表,则在peer的元表重复1,2,3步骤,peer没有元表则进行第5步。(注意是在peer的元表上查找,而不是元表的__index查找)
- 在userdata的元表umt找,如果name是一个number类型,说明userdata可能是一个Array类型,则在value = umt[".geti"]找,如果value为function(luafunction或者cfunction)则call这个function,function的返回值赋值给userdata.name。如果name不是number类型,则value = rawget(umt, name),value不为nil,返回value,value为nil,进行第5步
- 在umt的gettable找,gettable = umt[&gettag],如果rawget(umt, name)是一个function(luafunction或者cfunction)则call这个function,function的返回值赋值给userdata.name。否则,进行第6步。
- 如果umt有元表,则在umt的元表重复4,5,6步骤,umt没有元表则进行第7步。(注意是在umt的元表上查找,而不是元表的__index查找)
- 到了这一步还找不到,会判断userdata == LUA_NULL_USERDATA,如果是,则抛出异常"attemp to index %s on a nil value",否则进行第8步
- if (toluaflags & FLAG_INDEX_ERROR),抛出异常"field or property %s does not exist"
转载于:https://www.cnblogs.com/xsxjin/p/6859331.html
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- C开发lua模块(三) --- 返回userdata和结构体指针
- mtk打包/解包 boot.img, system.img, userdata.img, or recovery.img
- 使用userData兼容IE6-10,chrome,FF 及360等浏览器的本地存储
- 使用userdata和localstorage做跨浏览器本地储存
- Use IE userdata behavior as a client-side data storage
- 使用#default#userdata组件实现的可记忆内容的编辑器
- 大数据改变世界,UserData改变生活
- Vijava 学习笔记之CustomizationIdentification、 CustomizationUserData
- Android 映像文件 system.img, boot.img, ramdisk.img, userdata.img.
- IE 之 userData 模拟 localStorage
- Android ramdisk.img system.img userdata.img
- cookie and userdata
- android build 过程 (ramdisk.img、sytem.img、userdata.img)和 启动过程简单分析
- A Programmer's Guide to Data Mining 2:Get started with recommendation system(User based filtering)
- 刷Android模拟器下载的system.img和userdata.img到C8650
- JavaScript本地存储实践(html5的localStorage和ie的userData)
- tcp/ip学习笔记--第11章 UDP(user data protocol)
- chrome 49 版本 跨越 --args --disable-web-security --user-data-dir
- luajit 使用云风的int64库 负数 bad light userdata pointer
- delphi 7开发的系统在win 7下出现的 'Invalid data type for 'UserPreferencesMask'的解决