U3D开发:Mono和IL2CPP的区别_mono和il2cpp区别-程序员宅基地

技术标签: c#  

术语解释

C#

.NET Framework:是Windows的托管环境,可为其运行的应用提供各种服务。

主要包括两个主要组件:公共语言运行时(CLR),它是处理运行应用的执行引擎;.NET Framework类库,它提供开发人员可从其自己的应用中调试的已测试、可重用代码库。

MonoVM各平台运行时库,解决了C#不能跨平台的问题

组成组件:C#编译器、CLI虚拟机,以及核心类别程序库。

Mono的编译器负责生成符合公共语言规范的映射代码,即公共中间语言(Common Intermediate Language,CIL)。

工作流程

1. 通过C#编译器mcs,将C#编译器为IL(中间语言,byte code)

2. 通过Mono运行时中的编译器将IL编译成对应平台的原生码

三种转译方式

即时编译(Just in time,JIT):程序运行过程中,将CIL的byte code转译为目标平台的原生码。
提前编译(Ahead of time,AOT):程序运行之前,将.exe或.dll文件中的CIL的byte code部分转译为目标平台的原生码并且存储,程序运行中仍有部分CIL的byte code需要JIT编译。
完全静态编译(Full ahead of time,Full-AOT):程序运行前,将所有源码编译成目标平台的原生码。

JIT编译

        将IL代码转为对应平台原生码并且将原生码映射到虚拟内存中执行。JIT编译的时候IL是在依托Mono运行时,转为对应的原生码后在依托本地运行。

IL(Intermdediate Language)

        IL的全称是 Intermediate Language,很多时候还会看到CIL特指在.Net平台下的IL标准)。翻译过来就是中间语言。IL就是.net字节码
        它是一种属于通用语言架构和.NET框架的低阶的人类可读的编程语言。
        CIL类似一个面向对象的汇编语言,并且它是完全基于堆栈的,它运行在虚拟机上(.Net Framework, Mono VM)的语言。

IL代码如何生成:不管何种编程语言--->通过自身编译器--->生成IL中间代码

虚拟机是什么:解释执行IL代码的执行环境。游戏运行时--->加载到运行时库(Mono VM)

                        --->动态地编译成汇编代码JIT然后再执行

IL2CPP

解释:在得到中间语言IL后,使用IL2CPP将他们重新变回C++代码,然后再由各个平台的C++编译器直接编译成能执行的原生汇编代码

优点:可移植性强、尺寸小,运行速度快,相比Mono性能提升40%左右。

缺点:转换过程中不好调试、不直观;不支持热更新;

IL2CPP分为两个独立的部分:开发编译工具+runtime的环境库
1. AOT(静态编译)编译器:把IL中间语言(IL的字节码:.net字节码)转换成CPP文件。然后再利用平台的工具,来编译成本地的机器码。

        ex:

        IOS->IL2CPP->IL字节码->cpp代码->xcode来编译,生成本地机器码

        Android>IL2CPP->IL字节码->cpp代码->Android的NDK编译成本地机器码


2. cpp运行时库(也可以说是IL2CPP VM):例如垃圾回收、C#委托与事件、C#多线程的支撑和实现。也就是说,这个是为了支撑C#的语言特性,我们开发的一个运行时候的库,来对C#的一些特性来作支撑。

运行原理:

程序语言--->自身编译器--->IL--->IL2CPP--->C++Code--->Native C++ Compiler---> Native excutable asm ---> IL2CPP VM

Untiy为什么要推出这个技术

1.跨平台移植:如果是Mono--->我们需要每个平台实现mono的虚拟机--->不受unity控制;

2.Mono使用.net也是有版权在这里,受限于Mono;

3.Mono性能问题--->不如CPP直接--->编译成本地的机器码。

4.解决苹果上的编译问题:IOS不支持jit编译,机器码被禁止映射到内存,即封存了内存的可执行权限,变相的封锁了jit编译方式。

IL2CPP是如何处理C#中的反射机制

C#里面有反射(Type t = Type.GetType("TypeName");),但是C++里面没有反射。就需要把C#类型--->编译成C++类、为C++类做一个type描述的类型(类的名字、类的成员的函数指针)--->编译时的时候来生成这样的对象,或者对一个类来注册我们的类型描述

ex:调用反射的时候:对象实例.xxx方法--->获取这个类型描述对象,根据我们的方法的名字,静态转成我们的函数指针。

Func函数指针 = 类的成员--->成员函数的地址;

MethodInfo f = t.getMethodInfo("Test");就是从类的描述里面获取"Test"的函数指针--->编译时就确定的,就可以调用这个函数了。

IL2CPP是如何支持C#的GC的

C#本身就有GC,但是C++没有,需要IL2CPP的runtime库实现这个GC,采用的是标记+清除算法

1.遍历所有的对象,找出对象的引用关系,把这些正在使用的(引用对象)标记出来;

2.清除掉没有标记的对象;

但是这两步都会占用计算资源,我们就会卡住主线程,导致我们瞬间的fps下降,游戏卡了一下。

我们释放内存,还资源给OS的时候,有可能引发内存碎片--->可用内存变小--->就需要用缓存池,自己来定义我们的内存分配的方式,减少内存碎片

IL2CPP如何处理C#中的委托和事件

C#中,先定义一个委托的类型:delegate void OnClick(); OnClick委托变量->里面有n个回调函数(Click += this.click1),触发这个回调调用的时候,里面的n个函数都被触发。

需要定义一个数据结构,对象实例的指针、成员函数->函数指针地址。C++调用这个类型的这个方法,传递this对象,跳到对应的函数地址来执行就可以了。

Native:机器码 

Mono和IL2CPP的区别

        早期,C#是微软的,只会在Windows平台运行。为了解决这个问题,引入了Mono,它是开源跨平台的,其实是在各个平台实现了套Mono的虚拟机,这样你的代码就能运行在各个平台了。Mono的核心原理是,将C#代码,转化成IL 中间代码,然后通过各个平台的Mono虚拟机解释执行,在运行时,解释的过程中,最终转化成了机器码。

        而 IL2CPP,是在各个平台,先将 C# 转化成 C++ 代码,然后通过各个平台的C++编译器直接生成了机器码,也就是在你发包的时候已经是机器码了,所以很快。

        另外,L2CPP 生成出的项目无法反编译,这相当于将C#代码加密了;而 Mono生成出的项目,是可以ILSpy 反编译出来的。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Niiiinomiya/article/details/134950241

智能推荐

(附源码)计算机毕业设计SSM智能导诊系统_智能预测和诊断系统界面设计-程序员宅基地

文章浏览阅读561次。智能导诊系统基于Web服务模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在不受时间、地点的限制来使用这个系统。智能导诊系统工作原理图,如图4-1所示:图4-1 系统工作原理图。_智能预测和诊断系统界面设计

【Python】解决UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 0: ordinal ...-程序员宅基地

文章浏览阅读220次。指定文件字符集为utf-8在文件头部加入以下代码:import sysreload(sys)sys.setdefaultencoding('utf-8')_unicodeencodeerror: 'ascii' codec cant encode character '\u2019' in position

UE、UI、UCD、UED四者的区别_ued,ui,,ue区别-程序员宅基地

文章浏览阅读1.2k次。 字面释义:UE(User Experience) : 用户体验 UI(User Interface) : 用户界面 UCD(User-Centered Design) :以用户为中心的设计 UED(User-Experience Design) :用户体验设计 UI(User Interface)即用户界面,也称人机界面。是指用户和某些系统进行交互方法的集_ued,ui,,ue区别

Java接口自动化框架系列05:Web接口自动化Demo例子详细介绍_java接口自动化案例-程序员宅基地

文章浏览阅读780次。Java接口自动化框架系列05:Web接口自动化Demo例子详细介绍1、提取到要测试的接口信息,并分析接口1.1、找到到你需要测试的接口,例如:新增角色,查询角色,删除角色例如:https://10.1.1.104/uim/doc.html1.1.1、新增角色接口地址:/uim/v1/role/add 请求方式:POST请求示例:{ "moduleName": "", "monitorEnabled": 0}响应示例:{ "code": 0, _java接口自动化案例

【计算机视觉】数字图像处理(四)—— 图像增强-程序员宅基地

文章浏览阅读3.1w次,点赞73次,收藏667次。数字图像处理(四)—— 图像增强图像增强的定义图像增强方法一、图像增强的点运算(一)灰度变换1. 线性变换2. 分段线性变换3. 非线性灰度变换对数变换指数变换(二) 直方图修整法1. 直方图均衡化2. 直方图规定化二、图像的空间域平滑(一)局部平滑法1. 超限像素平滑法2. 灰度最相近的K个邻点平均法3. 最大均匀性平滑4. 有选择保边缘平滑法5. 空间低通滤波法6. 中值滤波三、图像空间域锐化(一)梯度锐化法Sobel 与 Prewitt 算子(二)Laplacian 增强算子(三)高通滤波法四、图像的_图像增强

defconfig、 .config 、kconfig 与makefile和make menuconfig流程_make menuconfig .config-程序员宅基地

文章浏览阅读1.9w次,点赞18次,收藏135次。1.deconfig 文件:一般由平台厂商提供,内核编译用做.config的参考,注意:如果,缺少该文件,无法进行编译。文件位于:/kernel/../arch/arm/configs/xxx_defconfig2.kconfig 分布在各目录下的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make men_make menuconfig .config

随便推点

如何从GitHub上下载开源项目_如何在github上下载项目-程序员宅基地

文章浏览阅读3.1w次,点赞52次,收藏251次。  作为开源代码库以及版本控制系统,Github拥有超过900万开发者用户。随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及发现已有代码的首选方法。GitHub上有无数优秀开发者正在开发和维护的开源项目供大家学习与讨论,那么如何把大佬开源的项目clone到本地进行学习呢,下面几步就可以轻松搞定:1.安装Git,下载与安装可以参考这篇文章 Git下载与安装(Windo..._如何在github上下载项目

NVIDIA Jetson tx2 cuda和cudnn安装_刷机失败,手动离线安装_jetson tx2安装cuda-程序员宅基地

文章浏览阅读3.2k次。问题描述:在用官方刷机包安装cuda和cudnn是老是出错,故采取以下方式进行安装,能够完美解决该问题。由于在进行刷机时已经在host(用来刷机的主机)上下载了有关的安装包,故采用离线拷贝安装。一般在以下路径中可以找到:/home/yjq/configs/jetpack/jetpack_download #根据自己设置路径更改,一般在jetson_download下找即可安装cuda及cudnn拷贝安装脚本先创建一个cuda-l4t 文件夹(这里我写了在家目录下,根据自己习惯选择)._jetson tx2安装cuda

andorid实现pdf批注、笔记demo_android pdf文件批注-程序员宅基地

文章浏览阅读4k次,点赞3次,收藏10次。Andorid实现pdf批注、笔记demo1、兴建andorid项目2、导入pdf包implementation ‘com.lonelypluto:pdf-viewer:1.0.5’1、创建页面和java类1.1创建OutlineAdapterpackage com.example.myapplication.adapter;import android.content.Con..._android pdf文件批注

PDF文件编写者c#类库(版本1.26.0)_c# pdf annotation-程序员宅基地

文章浏览阅读1k次。下载examples of PDF files - 5.0 MB 下载C# class library (DLL) - 292.2 KB 下载demo project (including DLL) - 5.7 MB 下载source - 4.9 MB介绍PDF文件编写器c#类库PdfFileWriter允许您直接从。net应用程序创建PDF文件。这个库使您无法了解PDF文件结构的细节。要使用该库,您需要添加一个对附加的pdffilewritl .dll类库文件的引用,在使用该库并将pdffile_c# pdf annotation

ClickHouse的物化视图(Materialized View)使用介绍_clickhouse 创建物化视图详解-程序员宅基地

文章浏览阅读5.1k次。物化视图虽然能够自动更新数据,但是会带来一些性能上的损失,尤其是在基础表数据量较大的情况下。因此,在设计物化视图时,需要考虑这个因素,同时选择合适的刷新机制来平衡性能和数据实时性的需求。当基础表有数据插入时,触发器会自动插入相应的数据到物化视图中。)是一种特殊的表,它能够在底层数据更新后,自动更新自己的数据。数据更新包括两个方面的变化:基础表的数据修改和基础表的数据新增。另外,我们也可以手动刷新物化视图,甚至可以使用一些定时手段,实时或定时去触发它。如果基础表的数据修改,物化视图会自动更新。_clickhouse 创建物化视图详解

redis+sentinel+keepalived 高可用,可实现多台并单点访问_redis多台keepalived-程序员宅基地

文章浏览阅读6.7k次,点赞2次,收藏8次。redis+keepalivede主从高可用实操之前有写过redis+sentinel的哨兵机制主从的切换,这一次多了一个keepalived,是为了能够方便项目只支持一台访问,可是又要高可用的情况下,就可以执行此方案。本次主要讲的就是keepalived的配置,如何才能做到单台访问而实现高可用!_redis多台keepalived