tolua.setpeer学习记录

static int tolua_bnd_setpeer(lua_State *L) 
{
    // stack: userdata, table
    if (!lua_isuserdata(L, -2)) 
    {
        return luaL_error(L, "Invalid argument #1 to setpeer: userdata expected.");        
    }

    if (lua_isnil(L, 2)) 
    {
        lua_pop(L, 1);
        lua_pushvalue(L, TOLUA_NOPEER);
        lua_setfenv(L, -2);
    }        
    else
    {
        lua_pushvalue(L, 2);                //stack: u p p
        lua_setfenv(L, -3);                 //stack: u p
        lua_newtable(L);                    //stack: u p vt        
        
        lua_pushlightuserdata(L, &vptr);    //stack: u p vt lu
        lua_pushvalue(L, 1);                //stack: u p vt lu u
        lua_rawset(L, -3);                    //stack: u p vt            @vt[lu] = u
        //lua_pushvalue(L, 1);
        //lua_rawseti(L, -2, 1);

        lua_getref(L, LUA_RIDX_VPTR);       //stack: u p vt mt
        lua_setmetatable(L, -2);            //stack: u p vt

        lua_pushstring(L, "base");          //stack: u p vt "base"
        lua_pushvalue(L, -2);               //stack: u p vt "base" vt
        lua_rawset(L, 2);                   //stack: u p vt    
        lua_pop(L, 1);
    }

    return 0;
};

把C#对象在lua中对应的userdata(csobj)和一个lua table(peer)进行setpeer操作后:tolua.setpeer(csobj, peer)

1.把peer表设置为csobj的环境表,peer.base[&vptr] = csobj,  setmetatable(peer.base, vptrtable)

2.在csobj访问一个元素,csobj[key],会进行以下步骤:

  (1)在peer表直接查找,rawget(peer, key),如果不为nil, 则返回这个值。如果为nil,则进行第(2)不查找

 

 

 

如果userdata(u)和peer(p)表都不为空的话,会执行如下步骤:

1.lua_pushvalue(L, 2);                           把peer表复制压进栈顶                                                        此时虚拟栈:stack: u, p, p

2.lua_setfenv(L, -3);                      -3是u的位置,相当于把栈顶元素peer设置为u的环境表               此时虚拟栈:stack: u, p 

3.lua_newtable(L);                       创建一个空的table,压进栈顶                       此时虚拟栈:stack: u, p,vt

4.lua_pushlightuserdata(L, &vptr);          把一个轻量级的userdata压进栈顶,vptr是一个值为1的static int类型           此时虚拟栈:stack: u, p,vt, lu

5.lua_pushvalue(L, 1);           把栈底元素u复制压进栈顶                       此时虚拟栈:stack: u, p,vt, lu, u

6.lua_rawset(L, -3);                                执行vt[lu] = u, 直接赋值,忽略元表                  此时虚拟栈:stack: u, p,vt

7.lua_getref(L, LUA_RIDX_VPTR);            通过ref获取对应的一个table,压进栈顶                                                  此时虚拟栈:stack: u, p,vt, mt

8.lua_setmetatable(L, -2);                       setmetatable(p, mt)                                                                      此时虚拟栈:stack: u, p,vt

9.lua_pushstring(L, "base");                     把"base"字符串压进栈顶                                                                   此时虚拟栈:stack: u, p,vt,"base"

10.lua_pushvalue(L, -2);         把vt表压进栈顶                            此时虚拟栈:stack: u, p,vt,"base",vt

11.lua_rawset(L, 2);           p.base = vt                                                                                    此时虚拟栈:stack: u, p,vt

12.lua_pop(L, 1);             把vt弹出栈顶                             此时虚拟栈:stack: u, p

转载于:https://www.cnblogs.com/xsxjin/p/6854584.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值