基础概念和名词解释

  • 不同的编程语言:编程语言分为编译型和解释型语言,编译型指需要通过编译器,将源代码编译成机器码之后才能执行的语言;解释型语言不需要编译,在运行程序的时候才使用VM虚拟机逐行进行翻译,字节码也是解释型的一部分。

  • JIT:及时编译(just in time)

  • AOP:提前编译(ahead of time)

  • .NET框架:微软提出的C# 、 F#等语言的运行环境

  • il:C#中间语言字节码(比汇编高级一点),与平台无关

Mono/JIT

mono基于.NET框架提出的一种基于(CLR/JIT)的跨平台解决方案

流程

如图,

  1. 高级语言经过本地编译之后会变成中间语言,生成il并储存在dll/exe中,过程中生成元数据datameta,这个il与平台无关,具有非常良好的跨平台性

  1. il进入CLR,即公共语言运行时,进行JIT编译成本地的机器码

补充

PE文件

前面提到,高级语言经过本地编译器编译之后生成的中间语言会被存储在exe/dll当中,准确来说应该是存储在独立可执行单元PE当中。

PE是windows系统中可执行文件的统称。当然运行的时候是以.NET为环境。

JIT优势:

由于是运行时编译,JIT提供了许多灵活性,包括但不限于根据CPU特性生成优化代码,提供可影响il生成质量的编译选项。

CLR:

CLR(common language runtime)是.NET框架的核心,不仅仅有编译中间代码的作用,还包括内存管理,GC,线程管理等等。CLR是一种规范,而虚拟机如monoVM则是具体实现。

CLR结构图:

il2CPP/AOT

IL2CPP(Intermediate Language To C++)是 Unity 引擎中用于将 C# 代码转换的中间语言IL再次转换为为 C++ 代码的一种技术。它的主要目的是实现 AOT(Ahead-Of-Time)编译,以提高性能和兼容性。

mono:

il2cpp:

monoVM和il2cppVM

前面提到,C#作为一个解释型语言,需要通过虚拟机作为运行环境,就像mono有monoVM作为CLR实现一样。但是C++作为一个编译型语言,为什么还需要有il2cpp作为虚拟机?

IL2CPP 的“VM”:其实这里的“VM”并非传统虚拟机,而是指 IL2CPP 运行时库(如 libil2cpp)。它包含以下功能:

  • 垃圾回收(GC):通过集成 Boehm GC 或 Unity 自定义 GC 实现内存管理。

  • 类型系统与元数据:比如维护 C# 类型、反射等元数据。

  • 异常处理与线程管理:提供跨平台的基础运行时服务。

IL2CPP 与 CLR 的关系

  • IL2CPP 不是 CLR 的实现,但它仍然需要实现 CLI 规范中的核心功能(如 CTS、异常处理)。

  • 例如,C# 的 try-catch 语句在 IL2CPP 中会转换为 C++ 的异常处理机制(如果平台支持)。

为什么要转成C++?

  1. Mono VM在各个平台移植,维护非常耗时,有时甚至不可能完成。Mono的跨平台是通过Mono VM实现的,有几个平台,就要实现几个VM,

  1. Mono版本授权受限。很多C#的新特性无法使用导致Unity无法升级Mono。

  1. 提高运行效率,根据官方的实验数据,换成IL2CPP以后,程序的运行效率有了1.5-2.0倍的提升。

  1. 安全考虑。C#原本作为一门动态语言,使用JIT编译,JIT 允许程序在运行时生成新的代码,甚至修改现有代码。种动态性带来了灵活性,但也引入了潜在的安全风险。一些平台比如IOS,是直接不允许使用JIT编译的。而C++作为静态语言,使用AOT编译,就不会使用一些动态特性了。

参考链接(比我写的好,建议去看看原文

 Unity将来时:IL2CPP是什么?有了Mono为什么还需要IL2CPP?_il2cpp有用吗-CSDN博客 

 步步为营 C# 技术漫谈 三、公共语言运行库(CLR) - spring yang - 博客园 

 【计算机基础】IL代码-CLR平台上的字节码【什么是字节码?它与虚拟机的关系?】 - 小林野夫 - 博客园 

 IL2CPP 工作流程_unity自己下载的il2cpp安装在那个目录下-CSDN博客