一直以来很好奇,为什么unity可以跨平台开发,用了这么久还是有必要弄清楚的,所以今天特地研究了一下,记录下来,也供大家学习。

Unity介绍:

Unity3D主要包括两个部分:Unity EngineUnity Editor。提供了UnityEngine.dll和UnityEditor.dll两个动态库。

Unity Engine:C/C++编写,由平台相关代码,图形API、物理引擎、灯光、网络层接口等组成,编译为UnityEngine.dll,各平台不同,用户Shader代码也属于这一层的内容;

Unity Editor:IDE工具,大部分是由C#编写,插件也是用C#编写(调用UnityEditor.dll开发),用户脚本可用C#/JS/Boo编写,项目代码最后由Mono编译。

Mono介绍:

Mono是一个由Xamarin公司所赞助的开源项目。它基于通用语言架构(Common Language Infrastructure ,缩写为CLI)和C#的ECMA 标准(Ecma-335、Ecam-334),提供了微软的.Net框架的另一种实现。与微软的.Net框架不同的是,Mono具备了跨平台的能力,也就是说它不仅能运行在Windows系统上,而且还可以运行在Mac OSX、Linux甚至是一些游戏平台上。

Mono主要有以下部分组成:

  1. C#编译器——mcs
  2. 运行时:即时编译器JIT 与AOT。以及GC,类库加载器等等。
  3. 基础类库(BCL)
  4. Mono类库。提供了超出微软.NET的一些类,提供了许多额外功能,主要是用于构建其他操作系统上的应用

Unity与mono的交互:

众所周知的一点是,Unity3D游戏引擎本身是用C/C++写成的,将你的Mono运行时嵌入到unity之后,我们的应用就获取了一个完整的虚拟机运行环境。而这一步需要将“libmono”和应用链接,一旦链接完成, 我们再将Mono运行时初始化,一旦Mono运行时初始化成功,那么下一步最重要的就是将CIL代码加载进来,之后就可以解释执行C#代码了。

//链接方式:在unity c++中初始化
#include <mono/metadata/mono-config.h>MonoDomain* domain;
//mono_jit_init这个方法会返回一个MonoDomain,用来作为盛放托管代码的容器。
//其中的参数managed_binary_path,即应用运行域的名字。
domain = mono_jit_init(managed_binary_path);

CIL介绍:

CIL(Common Intermediate Language通用中间语言,也叫做MSIL微软中间语言)是一种代码指令集,CIL可以在任何支持CLI(Common Language Infrastructure,通用语言基础结构)的环境中运行,就像.NET是微软对这一标准的实现,Mono则是对CLI的又一实现。由于CIL能运行在所有支持CLI的环境中,那么就和和具体的平台或者CPU无关。这样就无需根据平台的不同而部署不同的内容了。

跨平台原理:

  • MCS编译器:Mono中C#编译器,是mcs把C#编译为dll(IL代码集合)。
  • JIT编译:或者又称为动态编译,将IL代码转为对应平台原生码(Native Code)并且将原生码映射到虚拟内存中执行。JIT编译的时候IL是在依托Mono运行时,转为对应的原生码后在依托本地运行。但它同时也会将编译过的代码进行缓存,而不是每一次都进行编译。所以说它是静态编译和解释器的结合体。
  • AOT编译:在程序运行之前,先把部分dll中的IL代编译为原生码(Native Code)

因此从上面可以看出unity跨平台的原理:使用mcs把c#(或者js)翻译成IL并生成dll或者exe,应用在平台执行时,先载入mono运行时,mono通过JIT,AOT将IL转成Native Code,然后运行在对应平台上。换言之mono运行的其实IL语言,IL也并非真正的在本地运行,而是在mono运行时中运行的,运行在本地的是被编译后生成的原生码。

IOS的IL2CPP:

使用Mono的时候,脚本的编译运行如下图所示:

简单的来说,3大脚本被编译成IL,在游戏运行的时候,IL和项目里其他第三方兼容的DLL一起,放入Mono VM虚拟机,由虚拟机解析成原生码,并且执行。但是使用IL2CPP将会增加一些步骤如下:

在得到中间语言IL后,使用IL2CPP将他们重新变回C++代码,然后再由各个平台的C++编译器直接编译成能执行的原生汇编代码。

好处:

  • 对于iOS平台,由于不允许运行时生成Native Code,因为ios被禁止了jit,因此上面方式采用Full-AOT的模式,利用IL2CPP将所有IL先转成C++ Code,而C++是可以跨平台编译执行的,因此有效的解决的ios问题。
  • 根据官方的实验数据,换成IL2CPP以后,程序的运行效率有了1.5-2.0倍的提升。
  • 可以利用现成的在各个平台的C++编译器对代码执行编译期优化,这样可以进一步减小最终游戏的尺寸并提高游戏运行速度。
  • 由于动态语言的特性,他们多半无需程序员太多关心内存管理,所有的内存分配和回收都由一个叫做GC(Garbage Collector)的组件完成。虽然通过IL2CPP以后代码变成了静态的C++,但是内存管理这块还是遵循C#的方式,这也是为什么最后还要有一个 IL2CPP VM的原因:它负责提供诸如GC管理,线程创建这类的服务性工作。但是由于去除了IL加载和动态解析的工作,使得IL2CPP VM可以做的很小,并且使得游戏载入时间缩短。

参考:

  • IL2CPP是什么:https://www.cnblogs.com/decode1234/p/10270911.html
  • unity mono  .net的关系:https://www.cnblogs.com/u3ddjw/p/10909975.html
  • 从游戏脚本语言说起,剖析Mono所搭建的脚本基础 :https://www.cnblogs.com/murongxiaopifu/p/4557365.html
  • Unity3D工具、Mono工具、内部脚本工作原理以及跨平台特性:https://www.jianshu.com/p/78b31c4a595b

unity跨平台原理相关推荐

  1. 【unity】unity跨平台原理

    跨平台 跨平台的含义是指一次编译,各个平台都可以运行. C/C++语言不能一次编译到处执行,因为C/C++的编译的结果是针对特定平台操作系统.处理器指令集而生成的本地代码(native code),那 ...

  2. 【Unity】Unity 跨平台及编译过程

    文章目录 Unity 跨平台的发展历程 具体实现方式 编译过程 CLR编译方式 CLR涉及概念 IL2CPP(跨平台过渡方案) 动态语言和静态语言 跟Java跨平台的区别 其他 Unity 跨平台的发 ...

  3. 输入输出 原理 java_java输入输出,书写规范,运行原理,跨平台原理(复习)...

    一个大概的java程序执行过程: java虚拟机跨平台原理:不管是什么系统,java源代码程序经过javac编译器编译成二进制的.class文件, .class文件在运行在jvm(虚拟机)上解释成对应 ...

  4. Java虚拟机(JVM)以及跨平台原理

    一. Java概述 1. Java语言概述 2. Java虚拟机以及跨平台原理 3. Java的主要就业方向 4. Java的不同版本 5. Java开发环境搭建 6. 第一个Java程序示例 7.  ...

  5. Java01-day01【发展史、跨平台原理、JRE和JDK、常用DOS命令、关键字、常量、数据类型、变量使用的注意事项、标识符、类型转换】

    java零基础入门到精通(2019版)[黑马程序员] 视频+资料:[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] &qu ...

  6. Unity Fog 原理 源码分析 案例

    Unity Fog 原理 源码分析 案例 效果图 简述 背景知识 clip空间坐标的范围 d3d (near,0), unity remapping to (0,far) 越靠近相机z值越小 open ...

  7. 2.Java语言跨平台原理?

    2.Java语言跨平台原理? 理解 为主 Java程序并非是直接运行的,Java编译器将Java源程序编译成与平台无关的字节码文件(class文件),然后由Java虚拟机(JVM)对字节码文件解释执行 ...

  8. Unity跨平台UI解决方案:可能是最全的FairyGUI系列教程.Part2

    回顾 上一节详情请看这里:Unity跨平台UI解决方案:可能是最全的FairyGUI系列教程.Part1 上一节介绍了:FairyGUI编辑器使用(控制台,纹理集....).元件.图片.动画.占位.装 ...

  9. 【JAVA】Java概述(1、Java语言发展史;2、Java语言跨平台原理;3、JRE和JDK;4、JDK的下载与安装)

    Java概述 重新学习Java第一篇 文章目录 Java概述 1.JAVA语言发展史 1.1Java语言 1.2Java语言发展史 2.Java语言跨平台原理 2.1平台 2.2跨平台 2.3跨平台原 ...

最新文章

  1. 【iOS-Cocos2d游戏开发之五】【1】多触点与触屏事件详解(单一监听、事件分发)...
  2. 【工业互联网】全球工业互联网十大最具成长性技术展望(2019-2020年)
  3. VC++基于APR实现禁止某个业务(开发行为控制软件用得着,例如上班禁止上QQ)...
  4. json对象转换成string的方法
  5. 玩转mini2440开发板之【编译烧录rootfs根文件系统全过程记录】
  6. 图文并茂重新认识下递归
  7. Win10文件夹空白处右键列表添加命令提示符
  8. 无线移动通信—文章导航
  9. 开源监控系统------Zabbix
  10. per_cpu机制的详解
  11. 代码管理学:遇到技术难题,要知道找谁
  12. 微信开发平台对接流程(Java版本)1
  13. mysql describe 分页_mysql之分页方式了解
  14. 运维知识-CentOS7-查看内存型号品牌等
  15. 2022年起重机械安全管理复训题库模拟考试平台操作
  16. 互联网服务架构设计漫谈(一)—设计考量点总览
  17. 乔布斯在斯坦福的演讲
  18. 彩色相机与灰度相机的成像原理
  19. 微型计算机的集成在微,微型计算机的( )集成在微处理器芯片上。
  20. 【脑洞】跳进直通地球另一端的洞中,人会如何运动?

热门文章

  1. TIOBE 8 月编程语言排行榜:没有一门语言能比得上 Python
  2. http-server简单HTTP服务器配置
  3. php自动调用打印机直接打印,PHP自动打印到网络打印机?
  4. 什么是类比估算法=自上而下的估算
  5. SPSS实现单样本K-S检验
  6. 完全重新安装IIS7
  7. 制作单词记录App(一)
  8. uniapp 动态切换应用图标、名称插件(如新年、国庆等) Ba-ChangeIcon
  9. 鸿蒙系统名字来历,鸿蒙系统名字含义_华为鸿蒙操作系统自己研发吗
  10. Linux操作系统汇编语言基础知识(图文代码)