热更新系列(一)——.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之后,然后翻译成原生代码