Mono是一个开源项目。 基于通用语言架构和C#的 ECMA标准,提供了.NET的另一种实现。并且具备了跨平台的能力,能在Windws、Mac、Linux甚至一些游戏平台上运行。

查看unity的Mono版本

 Debug.Log(Application.unityVersion);
        Type type = Type.GetType("Mono.Runtime");
        if (type != null)
            MethodInfo displayName = type.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
            if (displayName != null) Debug.Log(displayName.Invoke(null, null));

Mono的组成

  1. C#编译器 mcs
    编译器的作用是把c#源码编译成通用中间语言(MCIL/CIL)的字节码(ByteCode)。最后运行的时候通过通用语言运行库的转换,终可以被CPU直接计算的机器码(NativeCode)。

  2. Mono运行时
    提供了一个即时编译器(JIT),以及一个提前编译器(AOT),同时还有类库加载器,垃圾回收和线程系统等。在非Window平台需要Mono运行时来编译。

  3. 基础类库
    与微软的.Net框架兼容

  4. Mono类库
    提供了很多超越基础类库,超越.Net框架的类。

Mono运行时

mcs的作用是将c#源码编译为ECMA CIL的字节码,之后则需要Mono运行时的编译器,将字节码转译为机器码。Mono运行时提供了3种转译方式:

  • 即时编译(JIT)
    在运行过程中,将CIL的字节码转为目标平台的原生码
    1.运行当中 2.生成的是新代码 3.还得运行
  • 提前编译(AOT)
    在运行前,将CIL的字节码转为目标平台的原生码并储存起来,但还是有一部分转译需要用到JIT
  • 完全静态编译(Full AOT)
    完全杜绝JIT,IOS平台

IOS不能热更代码原因:
原因:IOS封了内存(或堆)的可执行权限,相当于变相的封锁了JIT的这种编译方式。

Lua代码为什么能热更:
Lua是使用C写的脚本语言,在运行时读入Lua编写的代码,在解释Lua时不是翻译为机器码,而是使用C代码进行解释,不用开辟可执行权限的内存空间,也不会有新代码执行,执行解释的是用C语言写出来的虚拟机。

CIL是什么

CIL是指令集。基于堆栈,而非通过CPU的寄存器来操作。和其具体的CPU架构无关。
CIL语言其实是运行在虚拟机中,具体到Unity 3D游戏引擎也就是Mono的 运行时。

IL2CPP

Unity使用Mono虽然解决了跨平台的难题,但是也引入了更多的难题。比如对于VM(前文提到的Mono运行时)的维护。这也是题主所提到的,有多少平台就需要维护多少个平台的VM。这是一个非常耗时耗费精力的工程,尤其在于Unity自身版本需要不停更新迭代的同时,再去维护老旧的VM虚拟机的升级与BUG相当困难。除此之外,虽然Mono本身是开源的,但是商业使用还是收到一定的版权限制,而低版本的MONO就无法使用C#的强大特性,如果做Unity开发的同学应该知道,前些年,只能使用Mono2.x的版本,导致非常多的C#代码无法实现。最后,因为MONO需要运行在虚拟机内,相比于编译成原生的CPP代码而言,效率非常低。还有一个问题是谷歌64位版本问题,MONO也无法解决。

现阶段Unity所使用的过渡方案是IL2CPP,它的原理也很简单,大概就是在IL代码之后,再进行一次转译,将其转化为Cpp代码,然后再利用不同平台的优化过的编译器,编译为对于平台的目标代码。

MonoMono是一个开源项目。基于通用语言架构和C#的 ECMA标准,提供了.NET的另一种实现。并且具备了跨平台的能力,能在Windws、Mac、Linux甚至一些游戏平台上运行。查看unity的Mono版本 Debug.Log(Application.unityVersion); Type type = Type.GetType("Mono.Runtime"); if (type != null) { MethodInfo .NET是微软搭建的开发者平台,主要包括: 1.支持(面向)该平台的编程语言(如C#、Visual Basic、C++/CLI、F#、IronPython、IronRuby…), 2.用于该平台下开发人员的技术框架体系(.NET Framework、.NET Core、Mono、UWP等), 1.定义了通用类型系统,庞大的CTS体系 2.用于支撑.NET下的语言运行时的环境:CLR 3..NET体系技术的框架库FCL 3.用于支持开发人员开发的软件工具(即SDK,如VS2017、VS Code等) 二、Mono是什么 微软的.NET框架本身只能在wind
最近遇到一个特殊需求,客户要求做一个运行在Linux上的软件,并且要有软件界面。考虑到不会GTK#,QT也不熟悉,所以想到还是用mono Windows Form(.net跨平台项目)比较好,这里记录一下做法。 1.首先得准备一些东西: 一台Windows电脑visual studio 2015 (其它版本也可以)一个虚拟机软件VisualBox(其它虚拟机软件也可以,这里以Visua
调试时遇到一个Mono运行时异常: ExecutionEngineException: Attempting to JIT compile method '...' while running with --aot-only. 最后发现原因是使用了泛型接口,导致Mono需要JIT编译,但在iOS平台中,Mono是以Full AOT模式运行的,无法使用JIT引擎,于是引发了这个异常。
转载链接:https://www.cnblogs.com/Jaysonhome/articles/13218403.html https://zhuanlan.zhihu.com/p/19972689 编译器的工作流水线: 源代码-词法分析-语法分析-语义分析-目标代码-链接-可执行文件 (现代编译器会复杂,比如优化) 虚拟机执行中间代码的方式分为 2 种:解释执行和 JIT(即时编译)。解释执行即逐条执行每条指令,JIT 则是先将中间代码在开始运行的时候编译成机器码,然后执行机器码...
一、开启图集功能 默认图集是不开启的, 需要在Editor>Project Settings设置中,将SpritePacker的Mode修改为Always Enabled(总是启用)或者Enabled For Builds(在构建时启用)。 二、设置图片的图集名称 在Texture Type为Sprite的图片设置中,填写Packing Tag字段。 Unity会自动将Packing
INoriEGOIST: 博主你好,我这边在使用2020.3.7f1版本时发现NDKRoot这条EditorPrefs实际key值不是AndroidNdkRoot而是AndroidNdkRootR19,一开始我都没想到这里会有问题然后在跑CI出错看unitylog的时候发现每次都是sdkjdk过了检测以后ndk报错最后去打开regedit注册表看了一眼发现NDKroot结尾还跟了一个R19(不得不吐槽一下这里每个root路径命名规则都不一致有的前缀安卓有的直接是直接加path例如jdkpath,NDK更离谱在前缀后缀都有情况下还多一个R19),这点不知道别的版本是不是有类似问题总之是真的花了很久才发现这个问题,如果有其他伙伴遇到类似的在batchmode获取路径一直NDK not Found可以尝试一下看看是不是写错了 c#堆和栈的区别 KindSuper_liu: 是的,已修正表情包 c#堆和栈的区别 master_yi_: 申请效率那里堆和栈是不是写反了? Unity IAP接入google支付文档(2022年最新) 换成最新的5.1.0版本 Unity(C#) 在List集合中根据概率取出一个值 不错 赞 解决了我的问题,之前其他地方也看到, 你这写得详细一点