ULua反射原理

  • 旧版本ULua
    • 使用的类
    • 实现方式
  • 现版本的ulua(tolua)
    • 实现方式
  • wrap:What ,How?
    • What:wrap是什么
    • How :Wrap使用与生成
    • How :对于庞大代码块,如何处理不想warp的文件?

(今天在研究ULua反射原理时搜索到的答案,进行的理解。如果后续确认有问题后会及时改正。)
所参考引用的文章 ulua、tolua原理解析

旧版本ULua

使用的类

System.Type类 :访问任何给定数据类型的信息。
System.Reflection.Assembly类 :用于访问给定程序集的信息,或者把这个程序集加载到程序中。

实现方式

lua调用C#是基于C#的反射。通过 System.Reflection.Assembly 把UnityEngine程序集加入到Lua代码中。然后通过 System.Type 查找出需要的类型加入到Lua代码中

private string script = @"
luanet.load_assembly('UnityEngine')
luanet.load_assembly('Assembly-CSharp')
GameObject = luanet.import_type('UnityEngine.GameObject')
ParticleSystem = luanet.import_type('UnityEngine.ParticleSystem')         local newGameObj = GameObject('NewObj')
newGameObj:AddComponent(luanet.ctype(ParticleSystem))
";
//反射调用
void Start () {LuaState lua = new LuaState();lua.DoString(script);
}

本质就是 在C#段写个通用反射函数, 然后将地址注册到lua全局表中

现版本的ulua(tolua)

实现方式

lua调用C#是基于去反射。

把所有的c#类的public成员变量、成员函数,都导出到一个相对应的Wrap类中,而这些成员函数通过特殊的标记,映射到lua的虚拟机中,当在lua中调用相对应的函数时候,直接调用映射进去的c# wrap函数,然后再调用到实际的c#类,完成调用过程。
具体可参考Unity3d ulua c#与lua交互+wrap文件理解
wrap调用提升了反射在效率上的不足,但是必须自己去wrap,所以大版本更新是可以用到的,小版本更新目前还是得用到反射

wrap:What ,How?

What:wrap是什么

wrap是对c#类的成员函数,成员变量,通过映射的方式。每个wrap文件都是对一个c#类的包装,在lua中,通过对wrap类中的函数调用,间接的对c#实例进行操作。

源C#文件:

using UnityEngine;
using System.Collections;  public class Example {  public string E1;  public Example (){  }  public LoginData(string e1){  this.E1 = e1;  }  public void Exm(string e1, string password, int id){  if (this.E1.Equals (e1) ) {  Debug.Log ("C# >>> Exm= {e1= " + this.E1);  } else {  Debug.Log ("Error!");  }  }
}

wrap后的文件

using System;
using LuaInterface;  public class ExampleWrap
{  public static void Register(IntPtr L)  {  LuaMethod[] regs = new LuaMethod[]  {  new LuaMethod("Exm", Exm),  new LuaMethod("New", _CreateExm),  new LuaMethod("GetClassType", GetClassType),  };  LuaField[] fields = new LuaField[]  {  new LuaField("E1", get_E1, set_E1),  };  LuaScriptMgr.RegisterLib(L, "Example", typeof(Example), regs, fields, typeof(object));  }  [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]  static int _CreateExample(IntPtr L)  {  int count = LuaDLL.lua_gettop(L);  if (count == 0)  {  Example obj = new Example();  LuaScriptMgr.PushObject(L, obj);  return 1;  }  else if (count == 1)  {  string arg0 = LuaScriptMgr.GetString(L, 1);  Example obj = new Example (arg0);  LuaScriptMgr.PushObject(L, obj);  return 1;  }  else  {  LuaDLL.luaL_error(L, "invalid arguments to method: Example.New");  }  return 0;  }  static Type classType = typeof(Example );  [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]  static int GetClassType(IntPtr L)  {  LuaScriptMgr.Push(L, classType);  return 1;  }  [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]  static int get_E1(IntPtr L)  {  object o = LuaScriptMgr.GetLuaObject(L, 1);  Example obj = (Example )o;  if (obj == null)  {  LuaTypes types = LuaDLL.lua_type(L, 1);  if (types == LuaTypes.LUA_TTABLE)  {  LuaDLL.luaL_error(L, "unknown member name E1");  }  else  {  LuaDLL.luaL_error(L, "attempt to index E1on a nil value");  }  }  LuaScriptMgr.Push(L, obj.E1);  return 1;  }  [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]  static int set_E1(IntPtr L)  {  object o = LuaScriptMgr.GetLuaObject(L, 1);  Example  obj = (Example )o;  if (obj == null)  {  LuaTypes types = LuaDLL.lua_type(L, 1);  if (types == LuaTypes.LUA_TTABLE)  {  LuaDLL.luaL_error(L, "unknown member name E1");  }  else  {  LuaDLL.luaL_error(L, "attempt to index E1on a nil value");  }  }  obj.E1= LuaScriptMgr.GetString(L, 3);  return 0;  }  [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]  static int Exm(IntPtr L)  {  LuaScriptMgr.CheckArgsCount(L, 4);  Example  obj = (Example )LuaScriptMgr.GetNetObjectSelf(L, 1, "Example ");  string arg0 = LuaScriptMgr.GetLuaString(L, 2);  obj.Equip(arg0);  return 0;  }
}

流程就是 Lua虚拟机启动时,将Wrap注册加载进去,然后Lua 即可调用 Wrap , Wrap调用C#的模式,实现了Lua调用C#

How :Wrap使用与生成


图源来自tolua之wrap文件的原理与使用

How :对于庞大代码块,如何处理不想warp的文件?

tolua# 不支持动态反射。动态反射对于重载函数有参数匹配问题,函数排序问题,ref,out 参数问题等等。
tolua#提供的替换方法是:

一、preloading, 把你未来可能需要的类型添加到导出列表customTypeList,同时也添加到dynamicList列表中,这样导出后该类型并不会随binder注册到lua中,你可以通过 require “namespace.classname” 动态注册到lua中,对于非枚举类型tolua#系统也可以在第一次push该类型时动态载入,当然也可在过场动画、资源下载、登录、场景加载或者某个的函数中require这个类型。
二、静态反射,参考例子22 GitHub_topameng/tolua。通过静态反射支持精确的函数参数匹配和类型检查。不会存在重载函数参数混乱匹配错误问题, 注意iOS必须配置好link.xml

ULua反射原理——自我理解,有问题请斧正,谢谢!相关推荐

  1. JavaScript中函数的四种调用方式(若有错误之处请斧正)

    函数的几种调用方式 一.一般形式函数的直接调用 fun(); 二.作为对象的方法调用 var obj = {name:"123",sayMyage:function(age){al ...

  2. 关于OpenGL ES 3D 光晕如何产生的自我理解

    2019独角兽企业重金招聘Python工程师标准>>> 星空图的自我理解:可以看作一个透明的半径很大的天球,然后在其表面上绘制大小不一的点,这样便可以够成星空图. 如何产生光晕的自我 ...

  3. 关于渗透的一些思路持续更新(自我理解)

    关于渗透的一些思路持续更新(自我理解) 先回忆一下 准确的是17年才接触到渗透以及ddos 其他hei产东西就不介绍了 接触的自我感觉有点迟 从最开始我也是从阿D明小子那些很傻瓜化的软件走过来的 但是 ...

  4. 读阿里中台战略思想有感—自我理解

    读阿里中台战略思想有感-自我理解 中台的意义在于避免项目工程建设的不断"造轮子",也就是当需求来临时,全部重新建设,核心公共模块的工程代码没有被重复利用. 阿里对于中台战略思想的实 ...

  5. Sparsity Quantization 之自我理解

    Sparsity & Quantization 之自我理解 Sparsity Quantization DNN的最初的动力是以precise为中心,但随着DNN在Edge的推广,Latency ...

  6. 我的python之路一初识python的自我理解

    初识python的自我理解 关于python的自我简记 我认识的python 怎么开始python的学习和使用 我尝试过的几个python学习的常用组合 关于python的自我简记 初识python是 ...

  7. 六式建站浅见,和大家一起分享,不足之处还望斧正。

    和leven(小の鱼)同志一起为广大IT朋友设计的六式资讯分享社区[http://www.sixtp.com],经过反复的锤炼,终成今天的六式第一版,在这里把第一版制作过程中的心得写出来和大家一起分享 ...

  8. 如何通过c语言获取ipv6邻居表,急求在vc++6.0中获取IPV6地址的方法,高手请进,谢谢!!...

    本人最近getaddrinfo函数获取本机IP地址,本机的IPV4地址能正确获得,但本机IPV6地址只能获得环路地址,即::1.为什么不能获得IPV6的Global地址或链路本地地址.恳请指点,不胜感 ...

  9. c语言编辑学生信息录入的程序,c语言编的学生信息管理系统小程序!!有不足的请指出,谢谢!!...

    c语言编的学生信息管理系统小程序!!有不足的请指出,谢谢!! #include #include #include struct st { char name[20]; int english; in ...

最新文章

  1. Linux使用netstat命令查看并发连接数
  2. Error running ‘xxx-web-order‘: Unable to open debugger port : java.net.Socke
  3. SpringBoot-MyBatis
  4. 十大排序算法之快速排序(两种方法)
  5. 网站服务器需要定期重启吗,定期服务器重启的好处和障碍
  6. Access 时间比较错误
  7. java中关键字、标识符、常量、变量、数据类型
  8. 中移动飞信2010Beta1.0体验版
  9. Unity中的layer和tag
  10. PTA 程序设计天梯赛(61~80题)
  11. 浏览器调试动态js脚本
  12. python 爬虫库 u_9个用来爬取网络站点的 Python 库
  13. 浅谈LBP原理和代码(基于Python)
  14. 改文件777的php,服务器文件目录权限777修改方法
  15. unity 遮挡剔除
  16. 【随便做做|线段树】POJ3667 Hotel
  17. ​​​​​​​排列组合基本原理及公式
  18. 一位想学习编程拯救他人的初中生
  19. linux用户禁止登录,Linux限制用户登录
  20. 在线学习系统源代码_学习系统设计和软件体系结构必看的5门在线免费课程

热门文章

  1. linux编程用到什么编程语言,学好编程第一步,你得学会用什么工具来提高编写效率...
  2. 素数筛法(传统普通、朴素筛法、埃式筛法、欧拉筛法(线性筛))
  3. 反用路由表实现物理隔离SAP服务器
  4. CST学习笔记4----------初级端口
  5. ubuntu搜狗输入法字体太小,繁体字 怎么办
  6. WAYOS版本OEM,替换WAYOS的LOGO,江边小鸟杰作啊
  7. 在Carla中加入可以使用的自己的车
  8. 物联网工程专业:这三年都学了什么
  9. 机房动环监控系统参数与功能
  10. 计算机课数据排序与筛选ppt,《计算机应用基础》PPT课件