1、关于 IL2CPP
① 字面意思:
IL2CPP 的字面意思很直白:
IL (Intermediate Language,中间语言) to (到) CPP (C++ 语言)
就是:"将中间语言转换为 C++ 代码"。
② 大致流程:
你写的 C# 代码(.cs 文件)先被编译成 IL (.dll 程序集),然后在项目构建(Build) 时,IL2CPP 会读取这些 IL 代码,把它转换成庞大的 C++ 源文件,最后再用平台自带的 C++ 编译器(如 MSVC、Clang、GCC)生成原生的机器码(.exe、.so、.a 或 .app)。
③ 实现的主要目的:
覆盖苹果IOS、WebGL平台:iOS 平台禁止 JIT 编译,只允许运行原生机器码。IL2CPP 提前生成原生二进制的方式(AOT编译),契合 iOS 的要求。同时,它也适用于 WebGL 等无法使用 JIT 的平台。
实现一个 IL 到 C++ 转换器,难度极高;IL2CPP 也并不是基于某个现成的开源项目改出来的,而是 Unity 官方从零开始、投入大量顶尖工程师自主设计和实现的。
2、关于 HybirdCLR
大致实现思路:
HybridCLR 是在 IL2CPP的 "IL 转 C++ " 这个步骤里,向C++ 代码里注入了一套解释器的实现代码 。让 IL2CPP 运行时接纳热更新代码。它是对IL2CPP的魔改。
3、 在Unity打包时,HybirdCLR具体是如何 "劫持" IL2CPP 的?
先了解 Unity 用 IL2CPP 打包时的 具体步骤:
Unity 先启动一个 Mono 环境 (
mono.exe)。在这个环境里,运行我们的主角 il2cpp.exe 。
把编译好的 C# 代码(.dll 文件) 作为"原料"喂给它。
il2cpp.exe经过一系列复杂的分析和转换,最终在指定的输出文件夹里,生成海量的.cpp和.h文件。最后,Unity 再调用平台自带的 C++ 编译器(比如 MSVC 或 Clang),把这些 .cpp 文件编译成最终的机器码,也就是你能玩到的游戏程序
关键在第2步上,这个il2cpp.exe(IL-C++)的转换器,就藏在你的 Unity 安装目录里。
具体路径如下:
Windows :
Unity安装目录\Editor\Data\il2cpp\macOS :
Unity安装目录\Contents\Frameworks\il2cpp\build\
HybridCLR 的具体步骤是:
具体操作是:
拿到源码 :拿到了
il2cpp.exe的源代码。植入代码:在源码的关键位置(比如处理类型、方法的函数里),插入大量的"拦截"判断。
重新编译 :把修改后的源码,编译成一个全新的、定制版的
il2cpp.exe。放回原位 :用这个定制版,替换掉 Unity 目录里那个官方的
il2cpp.exe。
4、HybridCLR 直接改了Unity安装目录的 il2cpp.exe ??
那不想用``了怎么办?怎么改回来?
注意:
HybridCLR 并没有 直接改动 你电脑上 Unity 安装目录里的 il2cpp.exe
它的工作方式很简单:(在你 HybridCLR - Installer 时)把Unity官方的 il2cpp 文件夹复制一份到你项目的 HybridCLRData 目录里,然后在这个副本上做手脚。 打包时,通过 Unity 开放的环境变量接口让编译器去读项目里的这个"魔改版"。
Unity完全支持把 IL2CPP路径指向自己的exe: 在手册中明确提到了这个环境变量:
IL2CPP_ADDITIONAL_ARGS。这说明 Unity 在设计 IL2CPP 时,刻意保留了让外部程序可以干预编译流程的接口。
注意的是,不是改动全局变量,而仅仅是 Unity 进程内的变量,这样能保证即使另开一个Unity项目,没有安装HybridCLR,也不会调用HybridCLR魔改后的il2cpp.exe
全局变量:
作用范围:整个操作系统。所有正在运行和将来会运行的程序都能读到它。
修改方式:通常需要管理员权限,通过系统的"环境变量"设置界面修改。
持久性 :修改后永久生效,直到你再次手动修改。重启电脑都还在。
潜在风险 :如果你用这种方式把
UNITY_IL2CPP_PATH指向了魔改版,那么你电脑上所有 Unity 项目、所有版本的 Unity 编辑器 ,在打包时都会去用那个魔改版。这会严重扰乱其他项目的正常打包。进程内变量 (HybridCLR 使用的方式):
作用范围 :只影响当前正在运行的、安装了 HybridCLR 的这个 Unity 编辑器进程。
修改方式 :不需要任何管理员权限,HybridCLR 的脚本在 Unity 内部直接调用
System.Environment.SetEnvironmentVariable完成。持久性 :不持久 。只要这个 Unity 编辑器进程关闭(你关掉 Unity 软件),这个修改就彻底消失,仿佛从未存在过。
安全性 :非常安全。它完全不会干扰你同时打开的其他 Unity 项目,也不会干扰你电脑上的任何其他程序,包括其他版本的 Unity 编辑器。