IL2CPP深入详解-总览
导语
该系列将会分为以下几个部分:
1. 总览(本文)
2. c++代码解析
3. 调试c++代码
4. 方法调用(一般方法,虚方法等)
5. 泛型共享
6. 类型与方法的 P/invoke 封装
7. 垃圾回收
8. 测试框架与使用
什么是IL2CPP
IL2CPP 是 Unity 自 4.6.1p5版本 提出的一种新的 scripting backend 方式,为Unity提供了更加高效、更加便携的虚拟机,IL2CPP分为两个独立的部分:
- AOT(静态编译)编译器
- 运行时库
其中AOT编译器将 IL(由.Net编译器输出的中间语言)转换为C++源码,而运行时库则会提供诸如 垃圾回收、线程/文件获取(独立于平台,与平台无关)、内部调用直接修改托管数据结构的原生代码 的服务与抽象。
AOT编译器
所谓AOT编辑器即 il2cpp.exe
在 Windows 系统中你可以在 Editor\Data\il2cpp 目录中找到它,
在 OSX 系统中你可以在 Contents/Frameworks/il2cpp/build,即Unity的安装目录中找到它。
il2cpp.exe 是由C#编写的受托管的可执行程序,它接受我们在Unity中通过Mono编译器生成的托管程序集,并生成指定平台下的C++代码。
IL2CPP的工具链如下图所示:
il2cpp-toolchain
运行时库
IL2CPP技术的另一部分是运行时库(libil2cpp),它的存在是为了支持IL2CPP虚拟机的运行,运行时库几乎完全由C++代码编写,并作为一个静态库与最终的可执行程序链接。(值得一提的是,IL2CPP技术十分得益于使用了libil2cpp这一更轻便的运行时库)
你可以通过查看 libil2cpp 的头文件了解其的代码构成(Windows 系统下的目录为Editor\Data\PlaybackEngines\webglsupport\BuildTools\Libraries\libil2cpp\include,OSX 系统下的目录为 Contents/Frameworks/il2cpp/libil2cpp),例如你可以在 codegen/il2cpp-codegen.h 文件中看到 il2cpp.exe 生成C++代码的接口以及 运行时库 的接口。
运行时库的另一关键功能是提供了垃圾回收,这一块内容将在后续的文章里再详细探讨。
AOT编译器是如何运行的
让我们来看一个例子(该例子运行在 Windows 系统下 Unity 5.0.1版本中)
开启一个新的工程,将如下脚本添加至主相机上:
- using UnityEngine;
- public class HelloWorld : MonoBehaviour
- {
- void Start ()
- {
- Debug.Log("Hello, IL2CPP!")
- }
- }
此时我们发布一个WebGL平台下的程序,并使用 Process Explorer 工具查看Unity通过什么命令行对 il2cpp.exe 进行了调用:
"C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe" "C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe" --copy-level=None --enable-generic-sharing --enable-unity-event-support --output-format=Compact --extra-types.file="C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt" "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll" "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll" "C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput"
这个命令行看起来又复杂又吓人,不用担心,让我们逐步来解析它,
"C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe"
首先,Unity启动 mono.exe
"C:\Program Files\Unity\Editor\Data\il2cpp/il2cpp.exe接着启动 il2cpp.exe
剩下的命令行则是传递给 il2cpp.exe ,而非传递给 mono.exe的参数,首先这里传递了5个标识符给 il2cpp.exe:
–copy-level=None
告诉 il2cpp.exe 不要复制生成的C++代码.
–enable-generic-sharing
IL2CPP将会共享泛型以此来减少最终包体的大小。
–enable-unity-event-support
支持通过反射获取的Unity事件,保证代码能够正确生成。
–output-format=Compact
在生成的C++代码中,为类与方法使用更少的字符数来命名,这样会使得代码更难以调试,因为IL代码的命名将会发生改变(笔者注:应该类似于代码混淆),但是却能够被编译器更快编译,因为编译器所需要解析的字符数变少了。
–extra-types.file=”C:\Program Files\Unity\Editor\Data\il2cpp\il2cpp_default_extra_types.txt”
使用默认的 额外类型文件 ,这个文件会被加入到你的Unity工程里,并告知 il2cpp.exe 哪些泛型类型或者数组类型没有在IL代码中出现,却会在运行时被创建。
值得注意的是这些命令行也许会在后续的Unity版本中发生变化。最后,让我们看看剩下的三条命令行。
“C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\Assembly-CSharp.dll” “C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\Managed\UnityEngine.UI.dll”
il2cpp.exe 接受所有应该被转换的 IL 程序集,在这里例子中它应该包含我的 MonoBehaviour脚本、 Assembly-CSharp.dll 以及 GUI assembly 和 UnityEngine.UI.dll ,很显然,上面的命令行里似乎少了些什么, 我的脚本引用了 UnityEngine.dll 和 mscorlib.dll,但是它们却没有被包含在上述的命令行中,那么它们在哪儿呢?事实上,il2cpp.exe 在内部对这些程序集进行了处理,因此在上述的命令行中它们不是必须的,Unity只显式地需要 根程序集(不被任何程序集引用的程序集)在命令行中被提及。
“C:\Users\Josh Peterson\Documents\IL2CPP Blog Example\Temp\StagingArea\Data\il2cppOutput”
最后的一个参数表示 il2cpp.exe 的输出目录,即 il2cpp.exe 生成代码的输出位置,如果你对此感兴趣的话,可以看一看生成目录下的C++文件,而这一块内容我们也会在后续的文章中对其进行详解。此外,如果你希望浏览生成目录下的代码的话,推荐在出包的时候选择 Development Player 模式,这样一来将会移除 –output-format=Compact 命令行,使得你的代码更具可读性。
PS:你可以通过改变 Player Settings 中的设置来观察 Unity 传递给 il2cpp.exe 的命令行的差异,例如将
Enable Exceptions 设置为 Full,那么命令行中就会增加 –emit-null-checks、–enable-stacktrace 、 –enable-array-bounds-check 三项.
IL2CPP没有做的工作
Unity官方并没有重写C#的标准库,因此当你发布一个Unity工程的时候,即使你选择了 IL2CPP 的方式来生成你的代码,所有在 mscorlib.dll、System.dll 等标准库中的代码都将使用Mono2X的方式来生成。
作者:StalkerME
链接:https://www.jianshu.com/p/7cfcb7b0cfe7
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
IL2CPP深入详解-总览的更多相关文章
- Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览
一.设计原理 1.Hadoop架构: 流水线(PipeLine) 2.Hadoop架构: HDFS中数据块的状态及其切换过程,GS与BGS 3.Hadoop架构: 关于Recovery (Lease ...
- Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 关于RPC(Remote Procedure Call),如果没有概念,可以参考一下RMI(Remot ...
- Hadoop3.1.1源码Client详解 : 入队前数据写入
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 紧接着上一篇: Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立 先给出 ...
- Hadoop3.1.1源码Client详解 : Packet入队后消息系统运作之DataStreamer(Packet发送) : 主干
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 在上一章(Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立) 我们提到, ...
- Hadoop3.1.1源码Client详解 : Packet入队后消息系统运作之ResponseProcessor(ACK接收)
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 紧接着上一篇文章: Hadoop3.1.1源码Client详解 : Packet入队后消息系统运作之D ...
- Ubuntu kill命令用法详解
转自:Ubuntu kill命令用法详解 1. kill 作用:根据进程号杀死进程 用法: kill [信号代码] 进程ID root@fcola:/# ps -ef | grep sen ...
- iOS开发——UI篇OC篇&SpriteKit详解
SpriteKit详解 SpriteKit,iOS/Mac游戏制作的新纪元 这是我的WWDC2013系列笔记中的一篇,完整的笔记列表请参看这篇总览.本文仅作为个人记录使用,也欢迎在许可协议范围内转载或 ...
- Java 8 中的 Streams API 详解
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- java日期详解
[TOC] 一.简介 java中的日期处理一直是个问题,没有很好的方式去处理,所以才有第三方框架的地位比如joda. 文章主要对java日期处理的详解,用1.8可以不用joda. 1. 相关概念 首先 ...
随机推荐
- eclipse与hadoop集成,运行wordCount1
搭好了hadoop集群之后,就该使用它了 第一步:下载hadoop eclipse的插件,将它放到eclipse\plugins的目录下,然后重启eclipse,点击windows->show ...
- freemarker模版引擎技术总结
FreeMarker语言概述 FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写. FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式 ...
- NAT网络下tcp_tw_recycle参数引起的故障
记录一次阿里云服务器故障排查思路 公司网络是nat 环境 问题: 同一个服务有两台服务器 172.19.19.252 172.19.19.187 两台服务器 要连node5 发现172.19.19.2 ...
- 品Spring:对@Autowired和@Value注解的处理方法
在Spring中能够完成依赖注入的注解有JavaSE提供的@Resource注解,就是上一篇文章介绍的. 还有JavaEE提供的@javax.inject.Inject注解,这个用的很少,因为一般都不 ...
- 使用lombok中的log
idea中安装lombok插件 引入lombok依赖 <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> ...
- 如何编译和调试Python内核源码?
目录 写在前面 获取源代码 源代码的组织 windows下编译CPython 调试CPython 小结 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 如果对Pyth ...
- Save your cats Aizu - 2224
Nicholas Y. Alford was a cat lover. He had a garden in a village and kept many cats in his garden. T ...
- 单元测试实践(SpringCloud+Junit5+Mockito+DataMocker)
网上看过一句话,单元测试就像早睡早起,每个人都说好,但是很少有人做到.从这么多年的项目经历亲身证明,是真的. 这次借着项目内实施单元测试的机会,记录实施的过程和一些总结经验. 项目情况 首先是背景,项 ...
- selenium3与Python3实战 web自动化测试框架 ☝☝☝
selenium3与Python3实战 web自动化测试框架 selenium3与Python3实战 web自动化测试框架 学习 教程 一.环境搭建 1.selenium环境搭建 Client: py ...
- Celery的使用完成异步任务与定时任务
0917自我总结 Celery的使用 一.官方文档 Celery 官网:http://www.celeryproject.org/ Celery 官方文档英文版:http://docs.celeryp ...