1、Unity引擎是如何做到跨平台运行的

我们从基础概念开始,一步步走进真相:

程序集

一个.Net程序由一个或者多个程序集组成,程序集可以是库,也可以是应用程序。.Net中,库项目导出的文件格式为.dll,应用程序导出后的文件格式为.exe。

类似Flash项目,也是由库项目和应用程序项目组成。在Flash中,库项目导出后的文件格式为.swc,应用程序导出后的文件格式为.swf。

比如:一般Unity项目里包含这四个C#库项目:

vs编译之后,然后我们在项目目录的缓存目录Library\ScriptAssemblies下,能找到对应的四个dll文件:

CIL(Common Language Runtime)

刚才我们提到C#库项目导出之后生成的是一个DLL文件, 这个DLL文件里,存放的是CIL代码集。

它是微软在发布.Net框架的时候,一起发布的一个语言。CIL语言大概长这个样子:

里面有几个我们很熟悉的词汇,Hello,world,System.Consolve::WriteLine。没错,它的功能就是输出Hello,world。

它原本的C#程序是这样:

在.Net平台下,所有的语言(C#,VB.NET等)都会被编译成CIL,然后运行在虚拟机上,由虚拟机把CIL转换成各个平台的原生码(CPU可直接执行的代码)。

是不是又有点像Flash,Flash程序也是运行在虚拟机上的。

虚拟机——Mono

大家在Unity项目中都见过Mono这个词,MonoDeveloper,MonoBehavior等,那Mono到底是个什么东西?

Mono是一个基于CLR的开源项目,允许引擎和用户的托管代码运行在每一个目标平台上。而CLR全称为通用语言运行平台(Common Language Runtime),是微软的.Net虚拟机。它其中两个主要作用是:1,编译——运行前把C#编译为CIL;2,运行——在运行的时把CIL转换成各平台的原生码。

这些是Mono支持的平台:Android,Apple iOS(iOS,Apple macOS,Apple tvOS,Apple watchOS),BSD (OpenBSD, FreeBSD, NetBSD),Linux,Microsoft Windows,Nintendo Wii,Sony PlayStation 3,Sony PlayStation 4,Sun Solaris

IL2CPP

刚才我们已经知道了Unity跨平台是如何做到跨平台的:

1、把C#通过Mono compiler(其他语言用的是Unity单独开发的一个Unity compiler),编译成CIL语言;

2、各个平台下的Mono虚拟机,运行CIL语言,转换成原生码给CPU执行。

其实Unity后来出了另外一个方案:IL2PP。

它会在项目转成CIL之后,再把CIL转成CCPP,然后在运行的时候,把CPP加载进来,由各个平台的IL2PP VM转换成原生码。

Mono vs IL2CPP

Mono模式下编译出来的安卓包体:

\assets\bin\Data\Managed\Assembly-CSharp.dll 为游戏的控制逻辑,运行时调用。\lib\armeabi-v7a\
libmono.so包含了mono VM的功能

IL2CPP模式下编译出来的安卓包体:

\assets\bin\Data\Managed\已经没有了DLL文件。 \lib\armeabi-v7a\libmono.so变成了libil2cpp.so,包含了Mono模式下的DLL和IL2CPP VM功能

IL2CPP的好处是:

1、运行速度快(CPP转原生码比CIL快);

2、减少Unity公司的维护成本:Mono VM官方是不支持那么多平台的,所以很多平台的Mono VM都需要Unity自己去制作和维护,而C++编译器是本来各个平台都现成的。

缺点是:

1、包体会变大;

2、编译速度慢;

3、不支持JIT。

2、Mono如何运行CIL

这个部分将会告诉大家,IOS平台究竟有和特别之处,为什么在它上面实现代码热更新那么麻烦。

1、JIT(Just In Time)模式——在编译的时候,把C#编译成CIL,在运行时,逐条读入,逐条解析翻译成原生码交给CPU再执行;

2、AOT(Ahead Of Time)模式——在编译成CIL之后,会把CIL再处理一遍,编译成原生码,在运行的时候交给CPU直接执行,Mono下的AOT只会处理部分的CIL,还有一部分CIL采用了JIT的模式;

3、Full AOT模式——在编译成CIL之后,把所有的CIL编译成原生码,在运行的时候直接执行。

(留个坑:AOT模式下,编译出来的内容有两部分:原生码和CIL,它们是如何存放的,找了好多资料,没查到,本地想测试,但是环境暂时搭不起来,这个后面和IL2CPP一起研究)

Windows和Android系统采用的是JIT模式,那IOS用的哪一种呢?

我们看到,JIT模式是边运行,边翻译,支持运行时加载新的代码进来。而IOS是禁止内存的可执行权限的,不允许在运行过程中创建新的函数等,所以必须要提前编译好所有的代码,更不用说在运行时加载新的代码了。就是说,在IOS下,Mono采用的是Full AOT模式运行CIL。

转载于:https://juejin.im/post/5b6a4bb36fb9a04fa671cebf

Unity3D——C#编译到运行的过程分析相关推荐

  1. java运行时_java编译时与运行时概念与实例详解

    Java编译时与运行时很重要的概念,但是一直没有明晰,这次专门博客写明白概念. 基础概念 编译时 编译时顾名思义就是正在编译的时候.那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码.(当然只 ...

  2. 如何编译和运行C++程序

    如何编译和运行C++程序 C++ 和C语言类似,也要经过编译和链接后才能运行.我们在C语言课程的时候,讲了如何使用 VS.VC 6.0.VC++2010等常见开发工具,它们除了可以运行C语言程序,也可 ...

  3. Android开发学习笔记(二)——编译和运行原理(1)

    接着上一篇的内容,继续从全局了解Android.在清楚了Android的平台架构(可以看作是静态原理)后,还需要掌握其动态原理.动态原理包含两部分,一部分是编译原理,另一部分是运行原理.有人会说,搭建 ...

  4. 如何在Windows下使用Linux系统来编译和运行程序?

    很多开发人员都有这样的疑问:自己平时是在Windows下面办公的,而自己编写的程序的运行环境又是Linux的,如何从Windows切换到Linux呢?是不是要专门到Linux机器上去编写代码呢? 实际 ...

  5. java 程序编译和运行的过程

    Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来简单的说明整个流程. 如下图,Java程序从源文件创建到程序运行要经过两大步骤:1.源文件由编译器编译成字节码(ByteCode)  2 ...

  6. C++ 编译,运行过程 详解。

    要更深入了解C++, 必须要知道一个程序从开始到结束都干了些什么, 怎么干的. 所以我从C++编译到运行过程,解析下程序是怎么跑的. 首先,初略的说一下之前C++的编译过程,C++编译过程包括预编译- ...

  7. 今天终于将第一个 Android NDK 程序编译、运行成功

    今天终于将第一个 NDK 程序编译.运行成功. 起先看资料和书籍时,都要求安装 CygWin.我也安装了,并将 Sample: hello-jni 编译成功.编译的 LOG 如下:  LeoZheng ...

  8. IBatis.Net学习笔记二--下载、编译、运行NPetShop

    下载地址:http://ibatis.apache.org/dotnetdownloads.cgi 有最新版的IBastis.Net的源代码等,还有NPetShop的例子(例子比较老) 将NPetSh ...

  9. Notepad++如何编译、运行Java

    首先要让Notepad++编译和运行Java,前提是电脑里已经配置好了Java的环境(这里可以参考我博客里关于Java环境配置的那篇随笔). 在Notepad++上面的选项栏中找到 插件---> ...

最新文章

  1. 持续高温引发百姓热议 ***趁机放毒谋取暴利
  2. 如何保护企业网络免受勒索软件攻击 Vecloud微云
  3. Python 列表count()函数元素次数统计
  4. 小组项目第一次讨论总结
  5. ifix怎么装服务器系统上,ifix服务器和客户端配置
  6. RPC 和 RESTful对比
  7. ASP.NET页面刷新的实现方法
  8. 使用 JSONModel
  9. c语言给字母加密,C语言文字简单加密程序的实现
  10. opencv中关于cvtColor函数性能测试
  11. TSO、UFO、GSO、LRO、GRO和RSS介绍
  12. 二选一多路器Verilog
  13. 圣剑传说 玛娜传奇(Legend of Mana)(LOM)全防具取得方法
  14. 为什么要使用Typescript
  15. 【MySQL】必知必会知识点
  16. win10系统如何设置局域网服务器,小编解决win10系统设置局域网的解决方法
  17. 计算机控制技术课程配套教材习题解答(第1、2、3章)
  18. 初识C语言#define、指针、结构体
  19. JOL(java object layout --java 对象内存布局)
  20. vue实现瀑布流效果

热门文章

  1. 04-程序计数器(PC计数器)
  2. 重要接口—Serializable接口
  3. MySQL 用户创建及设置
  4. Android事件分发溯源详解
  5. linux动态链接库
  6. 微软颜龄Windows Phone版开发小记
  7. 编程之美 set 12 快速找出故障机器
  8. [iPhoneアプリ]iEscaper2攻略その6|龍の水晶
  9. 第十八节20181216
  10. mysql四种事务隔离级别