QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

C# 是如何执行的?你应该知道这些

  • 2019-10-28
  • 本文字数:1812 字

    阅读完需:约 6 分钟

C# 是如何执行的?你应该知道这些

为什么 Unity3D 可以运行 C#,C# 和 Mono 是什么关系,Mono 和 .Net Framework 又是什么关系?我们深入的来聊一聊这个话题!

从编译原理说起

一句话介绍编译器:编译器是将用某种程式语言写成的源代码(源语言),转换成另一种程式语言(目标语言)等价形式的程序。通常我们是将某种高级语言(如 C、C++、C# 、Java)转换成低级语言(汇编语言、机器语言)。


编译器以流水线的形式进行工作,分为几个阶段:源代码 → 词法分析 → 语法分析 → 语义分析 → 目标代码 → 链接 → 可执行文件。现代编译器还会更复杂,中间会增加更多的处理过程,比如预处理器,中间代码生成,代码优化等。


虚拟机是什么

虚拟机(VM),简单理解,就是可以执行特定指令的一种程序。为了执行指令,还需要一些配套的设施,如寄存器、栈等。虚拟机可以很复杂,复杂到模拟真正的计算机硬件,也可以很简单,简单到只能做加减乘除。


在编译器领域,虚拟机通常执行一种叫中间代码的语言,中间代码由高级语言转换而成,以 Java 为例,Java 编译后产生的并不是一个可执行的文件,而是一个 ByteCode (字节码)文件,里面包含了从 Java 源代码转换成等价的字节码形式的代码。Java 虚拟机(JVM)负责执行这个文件。


虚拟机执行中间代码的方式分为 2 种:解释执行和 JIT(即时编译)。解释执行即逐条执行每条指令,JIT 则是先将中间代码在开始运行的时候编译成机器码,然后执行机器码。由于执行的是中间代码,所以,在不同的平台实现不同的虚拟机,都可以执行同样的中间代码,也就实现了跨平台。


int run(context* ctx, code* c) {  for (cmd in c->cmds) {    switch (cmd.type) {      case ADD:      // todo add      break;      case SUB:      // todo subtract      break;      // ...    }  }  return 0;
复制代码


总结一下,虚拟机本身并不跨平台,而是语言是跨平台的,对于开发人员来说,只需要关心开发语言即可,不需要关心虚拟机是怎么实现的,这也是 Java 可以跨平台的原因,C# 也是同样的。推而广之,理论上任何语言都可以跨平台,只要在相应平台实现了编译器或者虚拟机等配套设施。

C# 是什么,IL 又是什么

C# 是微软推出的一种基于 .NET 框架的、面向对象的高级编程语言。微软在 2000 年发布了这种语言,希望借助这种语言来取代 Java,更多详细的介绍可以参看 C# Wiki。


C# 是一个语言,微软给它定制了一份语言规范,提供了从开发、编译、部署、执行的完整的一条龙的服务,每隔一段时间会发布一份最新的规范,添加一些新的语言特性。从语法层面来说,C# 是一个很完善,写起来非常舒服的语言。


C# 和 Java 类似,C# 会编译成一个中间语言(CIL,Common Intermediate Language,也叫 MSIL),CIL 也是一个高级语言,而运行 CIL 的虚拟机叫 CLR(Common Language Runtime)。通常我们把 C#、CIL、CLR,再加上微软提供的一套基础类库称为 .Net Framework。



C# 天生就是为征服宇宙设计的,不过非常遗憾,由于微软的封闭,这个目标并没有实现。当然 C# 现在还过得很好,因为游戏而焕发了新的活力,因为 Unity3D,因为 Mono。

.Net Framework vs Mono

Mono 是跨平台的 .Net Framework 的实现。Mono 做了一件很了不起的事情,将 CLR 在所有支持的平台上重新实现了一遍,将 .Net Framework 提供的基础类库也重新实现了一遍。



以上,Compile Time 的工作实际上可以直接用微软已有的成果,只要将 Runtime 的 CLR 在其他平台实现,这个工作量不仅大,而且需要保证兼容,非常浩大的一个工程,Mono 做到了,致敬!

Unity3D 中的 C#

Unity3D 内嵌了一个 Mono 虚拟机,从上文可以知道,当实现了某个平台的虚拟机,那语言就可以在该平台运行,所以,严格的讲,Unity3D 是通过 Mono 虚拟机,运行 C# 通过编译器编译后生成的 IL 代码。


Unity3D 默认使用 C# 作为开发语言,除此之外,还支持 JS 和 BOO,因为 Unity3D 开发了相应的编译器,将 JS 和 BOO 编译成了 IL。

小结

C# 在 Windows 下,是通过微软的 C# 编译器,生成了 IL 代码,运行在 CLR 中。


C# 在除 Windows 外的平台下,是通过 Mono 的编译器,生成了 IL 代码,运行在 Mono 虚拟机中,也可以直接运行将已经编译好的 IL 代码(通过任意平台编译)。


理论上,你创造了一门语言,并且实现了某一平台下的编译器,然后实现了所有平台下符合语言规范的虚拟机,你的语言就可以运行在任意平台啦。


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接:


https://mp.weixin.qq.com/s/pe0VR5wke9UB-a5BDmVRGQ


2019-10-28 16:454837

评论

发布
暂无评论
发现更多内容

NFT系统:数字藏品交易平台app开发功能

开源直播系统源码

NFT 数字藏品 数字藏品软件开发 数字藏品开发 数字藏品系统

技术分享 | 软件项目管理与跨部门沟通协作

霍格沃兹测试开发学社

多线程原理和常用方法以及Thread和Runnable的区别

共饮一杯无

多线程 8月月更

【Django | allauth】useprofile 用户模型扩展

计算机魔术师

8月月更

华为云联合信通院发布业界首个《云原生数据库白皮书》

IT资讯搬运工

技术分享 | 被测系统架构与数据流分析

霍格沃兹测试开发学社

全新EMQX Dashborad:易操作、可观测,集群数据尽在掌握

EMQ映云科技

物联网 IoT mqtt emqx 8月月更

【小程序项目开发-- 京东商城】uni-app之自定义搜索组件(下) -- 搜索历史

计算机魔术师

8月月更

helm实战之开发Chart

程序员欣宸

Kubernetes Helm 8月月更

技术分享 | 测试平台开发-前端开发之Vue.js 框架的使用(二)

霍格沃兹测试开发学社

软件测试 | 测试开发 | app自动化测试(Android)-- 属性获取与断言

测吧(北京)科技有限公司

自动化测试

内网穿透是什么意思?有什么用?用什么软件好?

行云管家

运维 内网穿透 内网

主机监控是什么意思?用什么软件好?咨询电话多少?

行云管家

运维 主机 主机监控

软件测试 | 测试开发 | 接口测试中如何使用Json 来进行数据交互 ?

测吧(北京)科技有限公司

json

华为云GaussDB践行云原生 带来极致弹性、全域可用和极简体验

IT资讯搬运工

技术分享 | 被测项目需求你理解到位了么?

霍格沃兹测试开发学社

软件测试 | 测试开发 | 使用 cURL 发送请求

测吧(北京)科技有限公司

curl

软件测试 | 测试开发 | 接口测试价值与体系

测吧(北京)科技有限公司

接口测试

【Django | 开发】面试招聘信息网站(快速搭建核心需求)

计算机魔术师

8月月更

【Django | 开发】面试招聘信息网站(处理产品细节和权限&美化页面样式)

计算机魔术师

8月月更

【Django | 开发】面试招聘信息网站(用户登录注册&投在线递简历)

计算机魔术师

8月月更

汽车制造企业如何最大化数据资产价值?

Kyligence

数据分析 智能多维数据库

云聚华为伙伴暨开发者大会GaussDB专场,与客户伙伴共话金融科技新发

IT资讯搬运工

技术分享 | 测试平台开发-前端开发之Vue.js 框架(一)

霍格沃兹测试开发学社

【Django | allauth】重写allauth重置密码方法

计算机魔术师

8月月更

【Django | 开发】面试招聘网站(增加csv,excel导出&企业域账号集成&日志管理功能)

计算机魔术师

8月月更

内容小程序化,是在线教育服务推广的最佳格式

Speedoooo

小程序 在线教育 移动开发 小程序容器

软件测试 | 测试开发 | 接口测试之HTTP、HTTPS 抓包分析

测吧(北京)科技有限公司

HTTP

leetcode 28. Implement strStr() 实现 strStr()(简单)

okokabcd

LeetCode 数据结构与算法

【Django | 开发】面试招聘信息网站(划分面试官权限&集成钉钉消息)

计算机魔术师

8月月更

华为云GaussDB深耕数据库根技术,助力能源行业数字化转型

IT资讯搬运工

C# 是如何执行的?你应该知道这些_文化 & 方法_易立_InfoQ精选文章