首页 > 其他分享 >xlua通信

xlua通信

时间:2023-04-14 17:48:43浏览次数:36  
标签:Name Utils 通信 TestXLua translator xlua table

xlua的wrap文件:Xlua 生成wrap文件 - 柯腾_wjf - 博客园 (cnblogs.com)

脑图:xlua - 百度脑图 (baidu.com)

相关扩展:XLua标签(转) - mc宇少 - 博客园 (cnblogs.com)

参考资料:

干货:xlua 是怎么和C#通信的?(二) - 知乎 (zhihu.com)

深入理解xLua基于IL代码注入的热更新原理 - iwiniwin - 博客园 (cnblogs.com)

Lua调用c#发生了什么? - 柯腾_wjf - 博客园 (cnblogs.com)

 

 

1.生成函数填充元表

// TestXLua.cs
[LuaCallCSharp]
public class TestXLua
{
    public string Name;
    public void Test1(int a){
    }
    public static void Test2(int a, bool b, string c)
    {
    }
}

 


Generatecode后生成的XXXwrap文件:
public class TestXLuaWrap 
{
    public static void __Register(RealStatePtr L)
    {
        ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
        System.Type type = typeof(TestXLua);
        //准备注册类的非静态成员(成员变量,成员方法等),主要为元表添加_gc和_tostring,并准备好method表、getter表、setter表。
        Utils.BeginObjectRegister(type, L, translator, 0, 1, 1, 1);
         
        //将下面生成的非静态包裹方法注册进对应的表中
        Utils.RegisterFunc(L, Utils.METHOD_IDX, "Test1", _m_Test1);//成员方法放进method表中
        Utils.RegisterFunc(L, Utils.GETTER_IDX, "Name", _g_get_Name);//成员变量get放进getter表中
        Utils.RegisterFunc(L, Utils.SETTER_IDX, "Name", _s_set_Name);//成员变量get放进setter表中

        //完成类的非静态成员的注册,主要为元表生成_index和_newIndex元方法。
        //_index元方法:当访问userdata[key]时,先依次查询之前通过RegisterFunc填充的methods、getters等表中是否存有对应key的包裹方法,
        //如果有就直接使用,没有则递归在父类中查找。
        Utils.EndObjectRegister(type, L, translator, null, null,
            null, null, null);

        //对类的静态值(例如静态变量,静态方法等)进行注册前做一些准备工作。主要是为类生成对应的cls_table表,
        //以及提前创建好static_getter表与static_setter表,后续用来存放静态字段对应的get和set包裹方法。注意这里还会为cls_table设置元表meta_table
        //cls_table:存类数据的表,Lua注册表[xlua_csharp_namespace]实际上对应的就是CS全局表,所以要在xLua中访问C#类时才可以直接使用CS.A.B.C这样的形式
        //Lua注册表 = {
        //xlua_csharp_namespace = {  -- 就是CS全局表
        //A = {
        //    B = {
        //       C = cls_table
        //    }
        //},
        //},
        // }
        Utils.BeginClassRegister(type, L, __CreateInstance, 2, 0, 0);

        //跟前面一样,注册到对应的表中
        Utils.RegisterFunc(L, Utils.CLS_IDX, "Test2", _m_Test2_xlua_st_);

        //结束对类的静态值的注册,为cls_table的元表meta_table设置_index元方法和_newIndex元方法。
        Utils.EndClassRegister(type, L, translator);
    }
    
    [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
    static int __CreateInstance(RealStatePtr L)
    {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            TestXLua gen_ret = new TestXLua();
            translator.Push(L, gen_ret);
            return 1;
        
    }

    //类成员方法
    [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
    static int _m_Test1(RealStatePtr L)
    {
        try {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            TestXLua gen_to_be_invoked = (TestXLua)translator.FastGetCSObj(L, 1);
            int _a = LuaAPI.xlua_tointeger(L, 2);
            gen_to_be_invoked.Test1( _a );
            return 0;
            {
               
            }
    }

    //类静态方法
    [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
    static int _m_Test2_xlua_st_(RealStatePtr L)
    {
            int _a = LuaAPI.xlua_tointeger(L, 1);
            bool _b = LuaAPI.lua_toboolean(L, 2);
            string _c = LuaAPI.lua_tostring(L, 3);
            TestXLua.Test2( _a, _b, _c );
            return 0;
    }
    
    //字段生成的get方法
    [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
    static int _g_get_Name(RealStatePtr L)
    {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            TestXLua gen_to_be_invoked = (TestXLua)translator.FastGetCSObj(L, 1);
            LuaAPI.lua_pushstring(L, gen_to_be_invoked.Name);
        return 1;
    }
    
    //字段生成的set方法
    [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
    static int _s_set_Name(RealStatePtr L)
    {
            ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            TestXLua gen_to_be_invoked = (TestXLua)translator.FastGetCSObj(L, 1);
            gen_to_be_invoked.Name = LuaAPI.lua_tostring(L, 2);
        return 0;
    }
}

总结:

生成代码会为类的非静态值都生成对应的包裹方法(字段改成get和set方法),并将包裹方法以key = func的形势注册到不同的表中。userdata元表的_index和_newindex负责从这些不同的表中找到对应key的方法,通过包裹方法实现对c#层对象的控制.

生成代码会为每个类以命名空间为层次结构生成cls_table表。与类的非静态值相同,生成代码也会为类的静态值都生成对应的包裹方法并注册到不同的表中(静态方法会直接注册到cls_table中而不是function表中)。而cls_table元表的_index和_newIndex负责从不同的表中找到对应key的包裹方法,最终通过调用包裹方法实现对c#类的控制。

local obj = CS.TestXLua()
obj.Name = "test"  -- 赋值操作将触发obj元表的__newindex,__newindex在setter表中找到Name对应的set包裹方法_s_set_Name,然后通过调用_s_set_Name方法设置了TestXLua对象的Name属性为"test"
CS.TestXLua.Test2()  -- CS.TestXLua获取到TestXLua类对应的cls_table,由于Test2是静态方法,在cls_table中可以直接拿到其对应的包裹方法_m_Test2_xlua_st_,然后通过调用_m_Test2_xlua_st_而间接调用了TestXLua类的Test2方法

 

标签:Name,Utils,通信,TestXLua,translator,xlua,table
From: https://www.cnblogs.com/mcyushao/p/17286534.html

相关文章

  • Python 实现tcp/ip协议&&CAN通信
    七层链路模型(Seven-LayerOSIModel)物数网传会表应--物理层、数据链路层、网络层、传输层、会话层、表示层(负责数据格式的转换和加密解密操作)和应用层。TCP/IP协议的四个层:应用层:应用层是TCP/IP协议中最高层,主要定义了各种应用程序的协议和数据格式。常见的应用层协议包括......
  • 基于WOA鲸鱼优化的5G通信系统资源分配优化matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:             2.算法涉及理论知识概要3.1鲸鱼算法       鲸鱼算法(WhaleOptimizationAlgorithm,WOA)[1]。鲸鱼优化算法(WOA)是2016年由澳大利亚格里菲斯大学的Mirjalili等提出的一种新的群体智......
  • S7-1200 Modbus RTU 通信概述
    S7-1200ModbusRTU通信概述Modbus具有两种串行传输模式:分别为ASCII和RTU。Modbus是一种单主站的主从通信模式,Modbus网络上只能有一个主站存在,主站在Modbus网络上没有地址,每个从站必须有唯一的地址,从站的地址范围为0-247,其中0为广播地址,从站的实际地址范围为1-247。Modbus......
  • k8s各组件作用和pod通信原理
    https://www.cnblogs.com/cyh00001/p/16488539.htmlkube-apiserverkube-apiserver负责和etcd交互,提供了k8s各类资源对象的增删改查及watch等HTTPRest接口,这些对象包括pods、services、replicationcontrollers等,APIServer为REST操作提供服务,并为集群的共享状态提供前端......
  • 使用组稀疏性的风险约束微电网重构 提出了一种新的分散重构方案,该方案需要MGM和LACs之
    使用组稀疏性的风险约束微电网重构在存在基于可再生能源的发电和负荷森林错误的情况下,考虑对现有配电系统和微电网进行系统重新配置任务。系统拓扑是通过解决机会约束优化问题获得的,其中强制执行配电线路的负载损失(LOL)约束和载流量限制。与各种配电系统重新配置再现类似,由......
  • 量子计算技术的前沿探索:量子比特和量子通信的应用
    ​ 量子计算技术是当前科技领域的热门话题之一,它的出现将会对计算机科学、密码学、物理学等领域产生深远的影响。量子计算机的核心是量子比特,它是量子计算机中的基本单位,与传统计算机中的比特不同,量子比特具有超强的计算能力和信息处理能力。量子比特的应用非常广泛,它可以用于解......
  • c sharp与python通信
    最近在学unity,想在unity调用python。因此学习了使用udp来建立通信。python发送,csharp接收python代码importsocketimporttimesock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)serverAddressPort=("127.0.0.1",10086)#5052定义localhost与端口,当然可......
  • 05-分布式通信
    一、Netty和网络通信(一)Netty框架简介​1、BIO​存在性能问题、可靠性问题、可维护性问题​​BIO的核心问题是同步阻塞publicvoidservice()throwsIOException{ServerSocketserverSocket=newServerSocket(port);......
  • BS结构的系统通信原理(没有涉及到java小程序)
    B/S结构的系统通信原理(没有涉及到java小程序)WEB系统的访问过程第一步:打开浏览器第二步:找到地址栏第三步:输入一个合法的网址第四步:回车第五步:在浏览器上会展示相应的结果关于域名:http://www.baidu.com/(网址)www.baidu.com是一个域名在浏览器地址上输入域名,回车之后......
  • 以太网通信控制板-控制板连接电脑网线然后作为TCP客户端和电脑端的TCP服务器通信
    <p><iframename="ifd"src="https://mnifdv.cn/resource/cnblogs/CH579_DTU_PBX/index1.html"frameborder="0"scrolling="auto"width="100%"height="1500"></iframe></p> 说明这节......