很有兴趣的话,可以去阅读下Jeffrey Ritchie的《Clr via C#》,目前出到第三版,英文好的话强烈推荐看英文版的,而且我有该电子书和实体书。
下面讲下我的理解:大致上不会出什么差错的,细节部分你可以参照上面的书籍!
1 首先,c#源码经过c#编译器被编译成托管模块(IL中间代码、元数据(Metadata))
2 然后,使用C#编译器以及程序集链接器(Assembly Linker ---- ALexe)将上述托管模块以及项目的资源文件Combine(整合)成一个程序集(Assembly)
上述程序集就是你所看到的exe文件或者dll文件等等,程序集中包含了manifest描述文件,是该程序集内容以及关系的一个清单,具体的内容你可以参见JR的书跟Java中的类似!
双击该exe运行的时候:
3 最后,运行时,CLR装载对应的程序集,使用内部的三个即时编译器(常用的为JIT),再去根据本机的环境去进行相应的优化(针对CPU优化等等),即时的翻译成本地机器指令去执行。
还有一个本地化代码生成工具,NGenexe~~
这个最好能去看看那本JR的神作!细节不是我三言两语能讲清的~~
程序集是在net中的名称,CLR在许多方面将它用做基本的管理单元,比如版本跟踪、部署。
一般输出形式为dll或exe文件。
模块是在软件设计中的名称与语言无关,主要是为了在设计时,软件结构清晰,比如设计打印模块,就是为了实现打印功能,其他模块要打印时就调用它。在C#中这个模块可以是一个或多个dll或exe,或者在一个程序集中有几个模块,看你在系统分析时如划分的。
道闸损失清单写法如下。写清名称、单价、数量、总价、因损坏失引起的连带损失。
类型引用信息:运行库用来将类型引用映射到包含其声明和实现的文件的信息。该信息用于从程序集导出的类型。
CLR是net 的核心框架的一部分,在学习clr的时候要了解一个程序集。
程序集包含了一个清单,这个清单相当于一个目录,描述了程序集本身的信息,例如程序标识(名称丶版本丶文化)丶程序集包含的资源(Resources)丶组成
程序集的文件。清单之后就是元数据了。如果说清单描述了程序集自身的信息,那么元数据则描述了程序所包含的内容。这些内容包括:程序集包含的模块丶类型丶类型
的成员的可见性等。注意,元数据并不包含类型的实现,有点类似于的h头文件。在net中,查看元数数据的过程叫做反射。然后还包含CIL的程序代码。
我们知道程集中的CIL代码是不能直接运行的,还需要CLR的支持。总的来说,CLR是一个软件层的代理,它管理了net程序集的执行,主要包括:管理应用程序域丶加载
和运行程集丶安全检查丶将CIL代码即时编译为机器代码丶异常处理丶对象析构和垃圾回收等。
CLR有点类似于JAVA的虚拟机。
CLR的主要作用:NET 程序集(CIL代码)————————CLR(转换成本地机器代码)——————————本地系统
CLR以什么样的形式位于什么位置:由于CLR本身用于管理托管代码,因此它是由非托管代码编写的,并不是一个包含托管代码的程序集,也不能用IL DASM查看。它位于
C:\SystemRootMicrosoftNET\Framework\版本号下,视安装的机器不同有两个版本 一个工作站msorwksdll 和一个服务器的版本 mscorsvrdll
CLR是如何运行的: *** 作系统在运行exe时,首先会检查PE头,根据 PE来创建合适的进程。接下来会检查是否存在CLR头,如果存在,就会立即载入MsCoreedll。这个库文件是net框架的核心组件之一,注意它也不是一个程序集。MsCoreedll 是一个很细的软件层。加载了MsCorEEdll之后,会调用其中的_CorExeMain()函数,该函数会加载合适版本的CLR。 在CLR运行之后,程序的执行权就交给了CLR CLR会找到程序的入口点,通常是Main方法,然后执行它。这里包含了以下过程:1
加载类型 2验证 3即时编译。
可以看出来采用这种架构的一个好处就是net程序集可以运行在任何平台上,不管是Windows丶UNIX,还是其他 *** 作系统,只要这个平台拥有针对于该 *** 作系统的net框架就可以运行NET程序集了。
被编译到同一个dll或exe中的程序就是处于同一个程序集中,在不同的dll或exe文件中的程序就是处于不同的程序集中。
net中的程序集就是一个编译器直接生成的dll或可执行的exe文件,包含程序集清单、元数据和MSIL等。是一个或者多个类型定义及资源文件的集合体。
1程序集和项目的关系,程序集,就是把CS文件编译后生成的存放CLR能识别的MSIL语言(微软中间语言)的一个文件(如一个DLL文件或者一个exe文件都叫一个程序集)。一个项目可以编译到一个程序集,也可以把多个项目编译到一个程序集里面,还可以把一个项目编译到多个程序集里。
2Bin(Binary,二进制的),obj(object,对象,目标码)Debug(调试)Release(发行)。根据字面意思也差不多知道它们各是干什么的了吧?
Bin文件夹,用于存放编译后生成的二进制文件。其下根据文件的不同用途,又建立了Debug和Release两个文件夹,分别存放用于调试和用于最终发布的文件。
obj文件夹,存放每个模块的编译结果。为了效率,NET默认采用增量编译,即每次只重新编译改动过的模块,这样就有必要把每个模块的编译结果分别存放。
3第1点已经说过,一个项目可以编译到多个程序集(技术可行,只是一般没那个必要),也说过一个DLL文件就是一个程序集。所以一个项目当然可以生成多个DLL文件。
同一个项目下可以有多个不同的命名空间。
4项目、解决方案、命名空间都是查询开发时的逻辑分类,和文件(物理概念)的多少没有必然联系。程序集是物理存放机制。
解决方案的概念要比项目大。所以你在Visual Studio的“解决方案管理器”里总是看到的项目位于解决方案的目录之下。而没有见过一个解决方案位于项目之下的。综上所述,一个解决方案里可以包含多个项目。项目包含不了解决方案。
一个项目可以有多个命名空间,多个项目也可以共用一个命名空间。
希望能帮上你。若有异议盼指教
请看 MyAppexe 的 nmake 脚本,它是一个很简单的仅由一个文件生成的应用程序:# build MyAppexe!if "$(DEBUG)" == "1"CPPFLAGS=$(CPPFLAGS) /MDdLFLAGS=$(LFLAGS) /INCREMENTAL!elseCPPFLAGS=$(CPPFLAGS) /MD!endifMyAppexe : MyAppobjlink $ /out:$@ $(LFLAGS)MyAppobj : MyAppcppclean :del MyAppobj MyAppexe如果此脚本不经更改便在 Visual C++ 上运行,它将成功创建 MyAppexe。它还将创建外部清单文件 MyAppexemanifest, *** 作系统会使用此外部清单文件在运行时加载依赖程序集。MyLibrarydll 的 nmake 脚本与之很相似:# build MyLibrarydll!if "$(DEBUG)" == "1"CPPFLAGS=$(CPPFLAGS) /MDdLFLAGS=$(LFLAGS) /DLL /INCREMENTAL!elseCPPFLAGS=$(CPPFLAGS) /MDLFLAGS=$(LFLAGS) /DLL!endifMyLibrarydll : MyLibraryobj
以上就是关于C#源代码编译成为本地代码的编译过程全部的内容,包括:C#源代码编译成为本地代码的编译过程、C#中程序集、模块和dll 之间的概念和关系问题、道闸损失清单怎么写等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)