zhaichao

标签: .net.net frameworkc#monounity
2017-04-23 14:39 425人阅读 评论(0) 收藏 举报

版权声明:本文为博主原创文章,未经博主允许不得转载。

做Unity项目已经有一年多了,知道Unity用Mono来实现跨平台,但是对于.net .net framework和mono一直只是一知半解。最近在做一个Unity项目需要从外部动态加载场景以及脚本,于是乎对.net framework和mono仔细研究了一发,这里也做一点总结。不过水平有限,如有错误求轻喷。
首先看一下github上.net core项目的主页,大概了解一下.net是干嘛的:
可以看到这个主页下面有几个子项目,其中有几个名字看上去很熟悉,比如coreclr,不就是CLR虚拟机么,corelx,看描述像是提供FCL的,cli,耳熟能详的通用语言基础结构,另外还有一个standard项目,里面是关于.net Standard方面的内容,Standard项目中有一个关于Standard version的文档:
另外在Standard项目的Readme中有如下描述:
所以可以总结一下,.net从一个抽象上来说其实是一个理念,即使得多种语言编写的程序能够通过一个通用的runtime运行在不同的操作系统以及硬件平台上。但光有理念不行,还需要实现,我们这里把对于.net里面的某个实现叫做.net platform(比如.net framework就是一个在windows上实现的.net platform,mono则是一个跨平台的.net platform)。一个.net platform想要达成.net的目标,就需要一些组件,比如上图中CLR通用语言运行时,比如FCL基础类库,比如各种语言的编译器,编译器编译出来的东西想要能在CLR中运行,那也需要遵循一定的标准,这就是CLI和CIL,CIL规定了编译输出的规则,而CLI规定了编译器输入语言的规则,只有符合这种标准的语言才能编译成CIL语言运行在CLR中。
好了现在有了CIL和CLR,程序员可以用符合CLI的语言比如C#编写程序了,然后将其编译成CIL,最后在CLR中运行。但是问题来了,程序员开发程序的时候需要用到一些功能以及数据结构,不可能所有的功能细节都自己实现,不然开发成本也太高了,所以就需要提供一些基础类库,方便程序员进行开发,那么需要提供哪些基础类库呢?这也需要一个标准,而.Net Standard就是用于这个目的,它规定了某个.net platform需要提供哪些API给开发者。这样的话加入一个开发者在.net platform A(比如.net framework)上开发了一个项目,然后想迁移到.net platform B(比如Mono)上,那么只要两个platform实现了同一个.net standard那么源代码就无需修改可以直接编译运行。
不过还有一个问题,假如我有一台机器,装了.net platform A(比如.net framework)和.net platform B(比如Mono),那么我在A上编译出来的一个.net程序放到B上可以运行么?理论上应该没问题,毕竟CIL是统一的,虽然一个是A的CLR一个是B的CLR,但是它们都是用来处理CIL程序,就像java代码编译出来既可以运行在JVM上也可以运行在delvik上一样。然而实际上不一定,因为CIL本身也不是一成不变的,它也有自己的版本,看下面这个文档:
https://msdn.microsoft.com/en-us/library/bb822049.aspx
里面的表格详细说明了.net framework和CLR版本之间的关系,从.net framework 2.0到3.5使用的是CLR 2.0,.net framework 4.0以后使用的是CLR 4.0,中间没有CLR 3.0版本。这也就意味着CIL语言本身也在发生变化,面向CLR 4.0编译出来的程序自然是不能运行在CLR 2.0上的。
说那到底什么是.net framework呢?个人理解从抽象角度说.net framework是对.net标准(这个标准具体包括CLI,CIL,.net standard等)在windows平台上的一套实现,具体上说.net framework包含一整套解决方案,包含许多字组件,比如编译器、CLR、FCL等等,其中每个组件都有自己的版本,比如编译器有自己的版本用于适应不同版本的语言,比如.net framework 3.5的编译器只支持到C# 3.0,最新已经到C# 7.0了;每个版本的.net framework提供的FCL也在不断丰富,比如System.LINQ到.net framework 3.5才有;CLR的版本也会不同,之前已经说过了。因此.net framework的版本其实就是其组件版本的一个集合,高版本的.net framework中的每个子组件都进行了一定的版本更新。
其实正常来说.net framework只是对.net标准的一套实现而已,其他的对于.net标准的实现完全可以将各种不同版本的组件组合起来用,比如我一套.net platform提供了.net framework 4.0的FCL和面向C# 6.0的编译器,但用的是CLR 2.0的运行时,这并没有什么问题,只要编译器和运行时匹配就行了(mono就是这么干的)。但是由于.net是微软提出来的而且.net framework是微软开发的,那别的.net platform实现自然就已.net framework为标杆,每个版本的.net framework都提供了一些新的features,支持.net framework x.x就是说这个.net platform实现了x.x版本.net framework的特性,比如下面是mono主页上的文档:
  
可以看到上面说的是.net 4.6 4.5,这里表示的其实是.net framework,这个图片的意思就是最新版本的mono已经实现了.net framework 4.6中支持C# 6的特性,以及此外还可以发现只有.net 3.5和2.0是mono完全实现了其所有特性。准确的说其实是mono实现了.net framework的大部分feature,并且还提供了一些mono自己的class library。Mono和.net framework大致有一个对应关系,如这篇文章所说:http://www.cnblogs.com/zhaoqingqing/archive/2016/08/12/5762867.html
这个表似乎不完全正确,mono 2.0实现了System.LinQ组件,这个组件在.net 3.5中提供,所以mono 2.0对应的应该是.net 2.0/3.5,即两者之和。不过还是可以当做一个参考。所以说加入一个程序集是用.net framework 3.5构建的,引用了一些dll如system.core以及system.linq,那么要想把其导入mono项目中,就必须保证mono的版本高于2.0,不然会找不到相应的引用。
还有一点需要注意,网上很多讲.net版本的时候讲.net framework version和CLR version混为一谈,有些时候说的.net 2.0指的其实是CLR 2.0。另外有些人把System.Environment.Version误以为是.ne framework版本,其实不是,msdn上说的很明确,这个值指的是CLR的版本:
另外还有一点值得注意,在vs中构建一个.net framework 3.5的项目时是,引用的System.dll是在系统的.net v2.0目录下的,也就是说.net framework不是独立的,而是依赖于.net framework 2.0.不过.net 4.0以后的版本好像就不是这样了,每次新版本都是独立的。
最后谈一下Unity,Unity为了跨平台使用了Mono,其使用的Mono版本可以通过代码或者命令行方式获得,unity forum上已经有牛人说明了:
http://answers.unity3d.com/questions/259448/how-to-determine-mono-version-of-unity-.html
我自己的测试结果是mono 2.0
查了一下mono官网,mono 2.0是08年的老古董(Unity居然还在用,貌似是版权问题,没有深究),而用vs打开一下Unity中的脚本,查看一下项目构建文件.csproj:
可以看到Unity用的是.net 3.5,所以难道Unity的脚本是用.net framework 3.5构建的?显然不是。
我们知道vs有一个东西叫VSTU,它最大的作用就是可以用vs的断点调试功能调试Unity Editor。Unity中的脚本在vs中打开的时候会构建一个VSTU项目。VSTU项目虽然跟普通VS项目看上去很像,但其实VSTU项目本质上并不是真正的vs项目,如果你右键项目->属性是没有反应的(VSTU 2.1以前有反应,之后就禁用了),而且右键项目中的引用也不会有添加引用选项,其实VSTU是把vs当做了一个功能强大的编辑器。
但VSTU不只是利用了VS进行语法检查这么简单,它的另一个作用就是断点调试。在没有断点调试的情况下,Unity使用自己的编译器进行编译,生成Assembly-CSharp.dll(在/Library/目录中),点击Play按钮的时候用的是这个dll,而用VS进行断点调试的时候则会用VS的编译器编译出Assembly-CSharp.dll以及pdb文件,在\Temp\UnityVS_obj\Debug\目录中,此时点击Play用的就是这个dll。当然build出exe的时候用的还是自己的编译器。
VSTU对项目进行了限制,不能直接在VS中添加新的dll,但可以拷贝到Unity项目的Asset目录下,这样Unity会重新构建VSTU项目,把拷进去的dll显示在引用列表里面。
VSTU构建的项目是基于.net framework 3.5的。因为Unity用的是mono 2.0啊,mono 2.0实现的feature包括.net framework 2.0和3.5,而UnityEngine.dll引用了System.Core.dll,而这个dll在.net framework 3.5才有,如果是是基于.net framework 2.0构建,那么第一有些mono 2.0支持的feature在vs里面就会找不到,另外也无法断点调试,因为编译通不过。
其实也可以在Unity的安装目录中寻找一些端倪,在windows下为:
C:\Program Files\Unity\Editor\Data\Mono\lib\mono\2.0
这个目录2.0目测就是mono的版本,目录中有很多dll,比如System.*.dll,这说明unity自带了mono项目,提供了mono 2.0中实现的基础类库。虽然Unity的脚本可以在像VS以及MonoDeveloper中打开,但是在build的时候用的还是Unity自带的Mono中的编译器,而Mono 2.0仅支持到C# 3.0,所以有些最新的语法在Unity里面是无法编译通过的(Unity 5.3.5 p8提供了一个新的编译器mono 4.4用于测试,但是似乎没有下文了)。
总结一下就是,Unity使用的是mono 2.0,支持C# 3.0,提供与.net framework 3.5/2.0 API兼容的类库(mono 2.0实现了.net framework 2.0 + 3.5的feature,但是没有实现.net framework 3.0的WPF的feature,所以官网的说法是.Net 2.0/3.5 framework profile),使用了与CLR 2.0兼容的mono runtime,因此用vs构建Unity的dll需要.net framework 3.5以下,不然runtime不兼容;如果要用到UnityEngine等Unity的功能必须用.net framework 3.5这个版本,不然vs项目找不到System.Core.dll,无法通过编译,如果只是一些工具类,不需要引用UnityEngine.dll,那么用.net framework 2.0构建是可以的。vs只是一个第三方构建工具,想要构建出Unity能用的dll就不能使用Unity(Mono 2.0)不支持的feature。
最后有一点之前一直在困扰我,但今天稍微有点想通了,就是Unity的Player Setting里面有个API compability Level:
这个只有两个选项:.Net 2.0和.Net 2.0 Subnet,这个说实话让人很不解,从字面上讲是指API兼容,那兼容到.net 2.0难道是指兼容.net framework 2.0的FCL API?但Unity可以用到.net framework 3.5的一些库啊。网上找了一通以后发现了如下网址:
https://docs.unity3d.com/412/Documentation/ScriptReference/MonoCompatibility.html
以及这个Question:
https://forum.unity3d.com/threads/unity-supports-c-3-5-or-2-0.111440/
其中有一句话很关键:
The 2.0 there is likely a good reflection of what you have at least
所以梳理一下就是.Net 2.0和.Net 2.0 Subnet是指编写的C#代码能够引用的函数集合的不同,如果选择了subset那么dll就不会被导入到项目中来。比如同一个项目用.Net 2.0和.Net 2.0 Subnet构建出来的目录如下,可以很明显看到两者的差别。
   
当新建一个Unity项目时,只会有一些核心的dll会被导入到项目中,其他的dll需要从外部拷贝到项目的Asset文件夹下,VSTU项目中是不能直接添加引用的,个人感觉VSTU对项目的限制有点多,像是把开发者当成傻子,因为你在用Unity那么这些功能就给你禁用掉,不过目测可以通过修改.sln或者.csproj文件来实现一些特殊需要。那.net framework 3.5呢?其实Unity支持的是.net framework 2.0 + 3.5,跳过了3.0,因为3.0是WPF的,Unity不需要,.net 2.0指的是你至少可以用哪些feature。
Unity最近因为加入了.Net基金会,出了几个用最新mono的测试版:
https://forum.unity3d.com/threads/upgraded-mono-net-in-editor-on-5-5-0b4.433541/
Unity 5.5.0 b4里面API compability Level增加了一个4.6选项,其实是把原来的mono 2.0换成mono 4.6进行测试,mono 4.6支持C# 6.0,并且开发者可以使用.net 4.6的API写程序,然而也不知道什么时候能有稳定版。而且mono都快要被淘汰了,以后目测都是IL2CPP了。

扒一扒.net、.net framework、mono和Unity相关推荐

  1. 185页深度报告 扒一扒AI金融的老底【附下载】

    来源:智东西 概要:2016年,中国爆出8家独角兽,总估值964亿美元位冠全球:2017年,毕马威全球百佳金融科技企业前三甲,蚂蚁金服.众安保险.趣店,皆来自中国:过往两年,中国成立的金融科技创企达1 ...

  2. 扒一扒EOS的前世今生

    扒一扒EOS的前世今生 EOS是什么?   EOS可以认为是Enterprise Operation System的缩写,即商用的一款分布式区块链操作系统,EOS主要为了解决百万级用户的使用问题,为企 ...

  3. 扒一扒MathType不为人知的技巧

    MathType作为一款编辑数学公式的神器,很多人在使用它时只是很简单地使用了一些最基本的模板,很多功能都没有使用.MathType功能比你想象中的大很多,今天我们就来扒一扒MathType那些不为人 ...

  4. oraclek导出表_全兼容Oracle?扒一扒浪潮K-DB是咋做的?

    [IT168 评论]"如果说Linux是类Unix操作系统,那么K-DB就是类Oracle数据库.会Unix的人,上手Linux要多少时间,则Oracle DBA上手K-DB就要多少时间.& ...

  5. 扒一扒.NET Core的环境配置提供程序

    前言 很久之前,在玩Docker的时候顺便扒了扒,最近,终于下定决心花了些时间整理并成文,希望能够给大家一些帮助. 目录 .NET Core中的配置 ASP.NET Core中的配置 扒一扒环境变量提 ...

  6. ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案

    ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案 原文:ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案 ASP.NET Core 从2.2版本开始 ...

  7. 扒一扒中断为什么不能调printf

    [导读] 大家好,我是逸珺. 前面说会写一下Modbus-RTU的实现,写了1000多字了,有兴趣的稍等一下哈.前面在一个群里看到一个朋友在一个串口接收中断里打印遇到了问题,今天聊下这个话题. 扒一扒 ...

  8. View绘制详解(三),扒一扒View的测量过程

    所有东西都是难者不会,会者不难,Android开发中有很多小伙伴觉得自定义View和事件分发或者Binder机制等是难点,其实不然,如果静下心来花点时间把这几个技术点都研究一遍,你会发现其实这些东西都 ...

  9. 人眼分辨 PPI_扒一扒,PPI、LPI、DPI分辨率三兄弟~

    今天我们来扒一扒这三个长得很像很像的分辨率三兄弟:PPI.DPI.LPI. 不急,沏一杯茶,咱慢慢侃~ 这三个后面的PI都是一个意思:per inch(每英寸). 所以这三个概念都是表明图像精细度的, ...

  10. 扒一扒AI的那些事儿

    随着人工智能的高速发展,人工智能技术得到了广泛的应用,并且从音乐和视频个性化推荐,到联网摄像头和自动驾驶汽车,AI正在逐步改变我们的生活方式.接下来小编带你扒一扒AI的那些事. 扒一扒AI的那些事儿 ...

最新文章

  1. Worktile 技术架构概要
  2. Java中关于枚举的7种用法
  3. js写的程序如何上线到linux,将 Node.js 应用发布到 Linux 应用服务 - Visual Studio | Microsoft Docs...
  4. Codeforces Round #741 (Div. 2) D2. Two Hundred Twenty One (hard version) 前缀和 + 分段模型
  5. 高德地图上线高考出行专项服务
  6. linq与数据库之添加
  7. 使用using关键字来自动清除对象资源
  8. Ubuntu安装Matlab
  9. python读取、写入txt文本内容
  10. 论一只爬虫的自我修养11:Scrapy框架之初窥门径
  11. 12864液晶中文资料JHD529m1
  12. Mac屏幕录制与视频压缩
  13. 双控 嵌入式. linux,大华 DH-ESS6024S-F 专业SAN磁盘阵列 网络智能存储服务器
  14. 极速办公如何在Excel中进行条件计数
  15. pm2启动node项目
  16. mysql获取数据库账号密码报错errorCode 1045, state 28000——常见5种解决办法
  17. 邮箱个性签名html模板,邮件个性签名大全_邮件的经典个性签名模板
  18. Docker_学习笔记
  19. python简单的绘制折现图
  20. [转载] 详解自动编码器(AE)

热门文章

  1. 如果要存ip地址,用什么数据类型比较好?
  2. 踩坑了,JDK8中HashMap依然会产生死循环问题!
  3. 面试:高频面试题:如何保证缓存与数据库的双写一致性?
  4. Tomcat 爆出高危漏洞!
  5. 我的4年学习心得:AI 应该是一个整体!
  6. 数据分析索引总结(下)Pandas索引技巧
  7. 【廖雪峰python入门笔记】字符串_转义字符的使用
  8. 我是如何在3个月内写出博士论文的?
  9. 7 Papers Radios | NeurIPS 2020最佳论文;全卷积网络实现E2E目标检测
  10. 550 万华人在美人才现状:7 诺奖、300 院士,320 八大常春藤高校终身正教授......