一、介绍
mono项目致力于能够使得开发人员在Linux用C#开发程序。
该项目的目标是创建一系列符合标准ECMA (Ecma-334和Ecma-335)的.Net 工具, 包括C #编译器和共同语言(CL 即 Common Language)执行平台(Platform)。与微软的.Net不同, Mono项目不仅可以运行于Windows系统内,还可以运行于Linux, FreeBSD, Unix, Mac OS X和Solaris。
组成:包含了一个C#语言的编译器,一个CLR的运行时,和一组类库
CLR常用简写词语,CLR是公共语言运行库(Common Language Runtime)和Java虚拟机一样也是一个运行时环境,它负责资源管理(内存分配和垃圾收集等),并保证应用和底层操作系统之间必要的分离。
mono VM: Mono虚拟机包含一个实时编译引擎,该引擎可用于如下处理器: x86, SPARC, PowerPC, ARM, S390 (32位模式和64位模式), x86-x64, IA64和64位模式的SPARC.该虚拟机可以将代码实时编译或者预先编译到原生代码.对于那些没有列出来的系统,则使用的是代码解释器。
名称
CLI: 通用语言架构(Common Language Infrastructure ,缩写为CLI)
CIL:CIL(Common Intermediate Language通用中间语言,也叫做MSIL微软中间语言)的一种代码指令集,CIL可以在任何支持CLI(Common Language Infrastructure,通用语言基础结构)的环境中运行,就像.NET是微软对这一标准的实现,Mono则是对CLI的又一实现。
JIT:JIT(Just-in-Time compilation,即时编译)
AOT(Ahead-of-Time,提前编译或静态编译)
二、mono运行时的嵌入
而在C/C++代码中,我们需要将Mono运行时初始化,一旦Mono运行时初始化成功,那么下一步最重要的就是将CIL/.Net代码加载进来。加载之后的地址空间将会如下图所示:
Mono的编译器——mcs:使用mcs编译该cs文件(C#编写的脚本),生成DLL文件。
使用C/C++调用C#/CIL语言:即提供脚本功能,将Mono运行时嵌入C/C++程序之后,在C/C++程序中调用C#中定义的方法。
如何在C#文件(脚本文件)中调用C/C++程序中的代码(游戏引擎)?
脚本--DLL |
mono运行时 |
C/C++实现的具体逻辑 |
将cpp文件和Mono运行时链接、编译,会生成一个a.out文件(在Mac上)
三、C#如何到native code的?
http://blog.csdn.net/honey199396/article/details/52397695
这篇讲的很完整:Unity3D -- Mono为何能跨平台?聊聊CIL(MSIL)
总结如下
代码的编译只需要分为两部分就好了嘛:
- 从代码本身到CIL的编译(其实之后CIL还会被编译成一种位元码,生成一个CLI assembly)
- 运行时从CIL(其实是CLI assembly,不过为了直观理解,不必纠结这种细节)到本地指令的即时编译(这就引出了为何U3D官方没有提供热更新的原因:在iOS平台中Mono无法使用JIT引擎,而是以Full AOT模式运行的,所以此处说的额即时编译不包括IOS)
CIL语言
.method public hidebysig static int32 Add(int32 a, int32 b) cil managed { // 代码大小 9 (0x9) .maxstack 2 .locals init ([0] int32 CS$1$0000) //初始化局部变量列表。因为我们只返回了一个int型。所以这里声明了一个int32类型。索引为0 IL_0000: nop IL_0001: ldarg.0 //将索引为 0 的参数加载到计算堆栈上。 IL_0002: ldarg.1 //将索引为 1 的参数加载到计算堆栈上。 IL_0003: add //计算 IL_0004: stloc.0 //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中。 IL_0005: br.s IL_0007 IL_0007: ldloc.0 //将索引 0 处的局部变量加载到计算堆栈上。 IL_0008: ret //返回该值 } //
U3D为何能跨平台以及CIL做个最终的总结陈词:
- CIL是CLI标准定义的一种可读性较低的语言。
- 以.NET或mono等实现CLI标准的运行环境为目标的语言要先编译成CIL,之后CIL会被编译,并且以位元码的形式存在(源代码--->中间语言的过程)。
- 这种位元码运行在虚拟机中(.net mono的运行时)。
- 这种位元码可以被进一步编译成不同平台的原生代码(中间语言--->原生代码的过程)。
- 面向对象
- 基于堆栈
即过程为source code --> CIL --> IL code --> native code