热更新系列(一)——.Net工作机制
Net 概念
什么是.NET .NET framework .NET core .NET Standard
.NET framework是针对windows平台下的应用.现在的版本是.NET Framework 4.8,很有可能这是.NET Framework的最后一个版本了。在未来并没有计划有新的.NET Framework版本.NET Core是开源跨平台开发,NET Core 3.0支持了WPF和Windows Forms。.NET Core 3.0 还支持UWP,WPF和Windows Forms三者的开发。.Net Standard是一个规范,它定义了Net Framewoek和Net Core必须实现的Api,它的出现为各种平台上开发的.Net人员解决了代码共享问题,但是仅用于开发类库,意思就是说如果你的类库是Net Standard规范的,那么此类库既可以是Net Framewoek也可以是Net Core类库..NET是.NET Framework和.NET Core核心的结合,旨在统一.NET平台,微软将其描述为“.NET的未来”
Net工作过程原理
CLI(Common Language Infrastructure) 公共语言基础
是为了实现.Net跨语言而定下的基础,任何语言只要实现这一套标准就可以运行在.Net之上.比如Mono
CLI已经成为了国际计算机标准规范,ECMA-335 - Ecma International (ecma-international.org)
CLI包括CLS和CTS:
CTS(Common Type System) 公共类型系统
解决不同语言数据类型不同的问题,如C#中的整形是int,而VB.net中的整形是Integer,通过CTS我们把它们两个编译成通用的类型Int32。
所有的.NET语言共享这一类型系统,在它们之间实现对接,简单说:就是把各种语言中的不同数据类型,转换成统一的通用的数据类型。
CLS(Common Language Specification) 公共语言规范
是一种最低的语言标准,定义了实现.Net语言的规则 属性 行为
凡是遵守这个标准的语言在.NET框架下都可以实现互相调用。简单说:就是把各种语言转换成统一的语法规范
CLR(Common Language Runtime) 公共语言运行时
可以理解为.Net虚拟机 Mono跨平台就是扩展了原来的CLR,现在.Net能跨平台也是增加了对其他平台的执行.
提供了必要的运行时服务,比如自动化内存管理,异常处理,垃圾回收等等,是.NET运行的核心
CIL(Common Intermediate Language) 公共中间语言
也称为IL MSIL,基于堆栈,又支持面向对象,运行在虚拟机之上
CLR就是来解释执行CIL的
CLR的编译过程:
参考连接
Net Framework,Net Core 和 Net Standard 区别 - 乐途 - 博客园 (cnblogs.com)
.NET Standard | Microsoft Docs
NET 5.0 正式版发布了!_dotNet全栈开发-CSDN博客
C# .NET .NET Framework .NET CORE 等的关系简介 - 陈松(Andy) - 博客园 (cnblogs.com)
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? - 小曾看世界 - 博客园 (cnblogs.com)
Mono和IL2CPP
Mono
当年Net的CLR只是针对于Window平台,使得与使用Net的不能实现跨平台,Mono扩展了.Net的CLR,在很多平台实现了一遍,所以可以使用Mono就可以跨平台了
这也是当时Unity为什么选中Mono的原因
特征
- 实现Mono vm比较麻烦 有多少个平台 就要在对应平台上实现一次 有时还不能完全能实现
- Mono明显的版本跟不上C#版本,这也是Unity 之前的问题 一直是Net2.0,现在能用.Net standard2.1,但是微软已经是.Net6了(原因就是实现困难)
- Mono使用Jit编译 所以构建很快
- APP Store发布规定:全新App必须在15年2月1日支持64位CPU,Unity引擎4.6.2之前的版本采用Mono的AOT机制提前将C#代码编译为机器识别的二进制代码,Unity官方为了支持IOS平台下64位的APP游戏,4.6.2之后的版本采用IL2CPP机制编译和处理IOS平台下的游戏,现在大多数都要求64位了,Unity的Mono是无法生成64位应用
IL2CPP
从上图可以看到,IL2CPP将生成的IL有重新编译生成了C++代码,然后由各个平台的C++编译器编译,IL2CPP VM只是实现了垃圾回收,内存管理
特征
- 相比Mono, 代码生成有很大的提高
- 可以调试生成的C++代码
- 程序的运行效率比Mono高,运行速度快
- 多平台移植非常方便
- 相比Mono构建应用慢
- 只支持AOT(Ahead of Time)编译
题外话:
Q:为什么unity的mono不支持64位打包
A:unity使用的是mono下的一个分支,不是完全的mono Unity uses a fork of the open source Mono project Mono overview - Unity 手册
chatgpt a:
Unity中使用的Mono是一个跨平台的实现了.NET Framework的运行时环境。在Windows平台上,Unity默认使用的是32位版本的Mono,因为它可以在所有版本的Windows上运行。
虽然有64位版本的Mono,但Unity并没有直接集成这个版本。这是因为Unity使用的Mono版本是定制的,而且在其它平台上,如macOS和Linux,也只支持32位版本的Mono。为了确保跨平台的兼容性,Unity团队决定只支持32位版本的Mono。
虽然在Windows上使用64位版本的Mono可能会提高性能,但是这样会使得Windows之外的平台上的性能变差,因为那里只有32位版本可用。因此,Unity团队为了平衡跨平台的兼容性和性能,选择了使用32位版本的Mono。
Unity和Godot都使用Mono作为它们的脚本运行时环境,但它们实现Mono的方式略有不同。
在Unity中,Mono是通过Unity自己的Mono实现,即Unity的Mono是一个轻量级的Mono实现。 Unity的Mono实现仅包含Mono的一个子集,包括Mono C#编译器、Mono运行时环境和C#标准库的一个子集。因此,Unity的Mono仅支持使用该子集的C#语言功能。
另一方面,Godot使用官方的Mono实现,该实现包括完整的Mono运行时环境和C#标准库,因此它支持完整的C#语言功能。此外,Godot的Mono支持C# 8.0和C# 9.0的一些新特性,而Unity的Mono仅支持C# 7.3的特性。
总之,虽然Unity和Godot都使用Mono作为脚本运行时环境,但它们实现Mono的方式略有不同,因此它们对C#语言的支持也略有不同
参考链接
【Unity游戏开发】Mono和IL2CPP的区别 - 知乎 (zhihu.com)
Unity将来时:IL2CPP是什么? - 知乎 (zhihu.com)
其他
Assembly-CSharp.dll和Assembly-CSharp-firstpass.dll
firstpass表示先编译,Editor表示放在Editor文件夹下的脚本。
根据官方的解释,它们的编译顺序如下:
Assembly-CSharp-filepass.csproj:所有在Standard Assets、Pro Standard Assets或者Plugins文件夹中的脚本
Assembly-CSharp-Editor-filepass.csproj:所有在Standard Assets/Editor、Pro Standard Assets/Editor或者Plugins/Editor文件夹中的脚本产生工程文件
Assembly-CSharp.csproj:所有在Assets/Editor外面的,并且不在(1),(2)中的脚本文件(一般这些脚本就是我们自己写的非编辑器扩展脚本)会产生工程文件
Assembly-CSharp-Editor-vs.csproj:所有在Assets/Editor中的脚本产生一个工程文件。
JIT(Just in Time) 动态(即时)编译,边运行边编译,把代码编译成IL 运行时候逐条翻译成原生码CPU执行
AOT(Ahead Of Time)运行前编译, 编译成IL之后,然后翻译成原生代码














