CLR的执行模型(3):加载

加载:

生成的每一个程序集,既可以是可执行应用程序,也可以是DLL。当然,最终是由CLR管理这些程序集中的代码执行。是否能执行,检查本机中是否安装.net Framework即可。

可执行文件在运行时,Windows检查文件头,判断需要32位还是64位地址空间。Windows还会检查头中嵌入的CPU架构信息,确保当前CPU架构符合要求。

WIndows检查EXE文件头,决定创建32位还是64位进程之后,会在进程空间加载MSCorEE.dll的x86,x64或者AMR版本。然后。进程的主线程调用MSCorEE.dll的一个方法,来初始化CLR,加载程序集,再调用其入口方法(main)。其后,托管应用程序启动并运行。

如果是非托管应用程序调用Load Library加载托管程序集,Windows会自动加载并初始化CLR以处理程序集中的代码。

一些额外的知识点(摘自博客):

托管代码:是一microsoft的中间语言,他主要的作用是在.NET FRAMEWORK的CLR执行代码前去编译源代码,也就是说托管代码充当着翻译的作用。托管代码就是Visual Basic .NET和C#编译器编译出来的代码。编译器把代码编译成中间语言(IL),而不是能直接在你的电脑上运行的机器码。中间语言被封装在一个叫程序集 (assembly)的文件中,程序集中包含了描述你所创建的类,方法和属性(例如安全需求)的所有元数据。这个程序集是.NET世界中的一个一站式购物 (译者注:就是程序集具有自描述性)部署单元。你可以拷贝这个程序集到另一台服务器上部署它--通常来说,这个拷贝的动作就是部署流程中唯一的一个操作。

托管代码在公共语言运行库(CLR)中运行。这个运行库给你的运行代码提供各种各样的服务,通常来说,他会加载和验证程序集,以此来保证中间语言的 正确性。当某些方法被调用的时候,运行库把具体的方法编译成适合本地计算机运行的机械码,然后会把编译好的机械码缓存起来,以备下次调用。(这就是即时编 译)

随着程序集的运行,运行库会持续地提供各种服务,例如安全,内存管理,线程管理等等。这个程序被“托管”在运行库中。

Visual Basic .NET和C#只能产生托管代码。如果你用这类语言写程序,那么所产生的代码就是托管代码。如果你愿意,Visual C++ .NET可以生成托管代码。当你创建一个项目的时候,选择名字是以.Managed开头的项目类型。例如.Managed C++ application。

非托管代码:非托管代码就是在Visual Studio .NET 2002发布之前所创建的代码。例如Visual Basic 6, Visual C++ 6, 最糟糕的是,连那些依然残存在你的硬盘中、拥有超过15年历史的陈旧C编译器所产生的代码都是非托管代码。托管代码直接编译成目标计算机的机械码,这些代 码只能运行在编译出它们的计算机上,或者是其它相同处理器或者几乎一样处理器的计算机上。非托管代码不能享受一些运行库所提供的服务,例如安全和内存管理 等。如果非托管代码需要进行内存管理等服务,就必须显式地调用操作系统的接口,通常来说,它们会调用Windows SDK所提供的API来实现。就最近的情况来看,非托管程序会通过COM接口来获取操作系统服务。

跟Visual Studio平台的其他编程语言不一样,Visual C++可以创建非托管程序。当你创建一个项目,并且选择名字以MFC,ATL或者Win32开头的项目类型,那么这个项目所产生的就是非托管程序。

这样子会导致一些混淆:当你创建一个托管的C++程序,那么构建出来的是一个中间语言程序集和一个扩展名为.exe的可执行文件。当你创建一个 MFC程序,构建出来是一个Windows原生代码的可执行文件,这个文件的扩展名也是.exe。这两个文件的内部结构是完全不一样的。你可以用中间语言 反汇编器(ildasm)来查看程序集的内部以及中间语言的元数据。如果尝试用中间语言反汇编器来查看一个非托管可执行文件,那么改反汇编器会告诉你这个 可执行文件没有包含一个合法的CLR头,所以不能被反编译。可见,这两个文件虽然有相同的扩展名,但是它们是完全不一样的。

原生代码:原生代码这个短语可以用在两个不同的上下文中。很多人会把原生代码跟非托管代码看作是同一个意思:用较老的工具构建的代码,故意采用Visual C++并使直接运行在计算机上,而且不运托管在运行库中。这可以是一个完整的程序,或者是一个COM组件,又或者是一个可以被托管代码利用COM Intero或者平台调用(PInvoke)所调用的DLL文件,COM Intero或者平台调用(PInvoke)可以帮助你在迁移到新的技术平台下依然能重用老代码的两个强大工具。

我更愿意说是非托管代码,因为这强调的是那些不能利用运行库所提供的服务的代码。例如在托管代码中,代码访问安全服务可以防止在另一个服务器上装载的代码运行特定的操作。如果你的代码运行的是非托管代码,那么你没法利用这样的保护服务。

原生代码的另一个意思是描述即时编译器的输出,那些实际上运行在运行库中的机械码。这些代码是托管代码,但是并不是中间语言,而是机械码。所以不要简单地假设原生就是等同于非托管。

原文地址:https://www.cnblogs.com/renzhoushan/p/10353186.html

时间: 2024-11-20 15:54:26

CLR的执行模型(3):加载的相关文章

01.由浅入深学习.NET CLR 基础系列之CLR 的执行模型

.Net 从代码生成到执行,这中间的一些列过程是一个有别于其他的新技术新概念,那么这是一个什么样的过程呢,有什么样的机制呢,清楚了这些基本的东西我们做.Net的东西方可心中有数.那么,CLR的执行模型是一个什么样的过程呢? 将源代码编译成托管模块 --> 将托管模块合并成程序集 --> 加载公共语言运行时 --> 执行程序集的代码 目录 将源代码编译成托管模块 将托管模块合并成程序集 加载公共语言运行时 执行程序集的代码 本地代码生成器:NGen.exe Framwork类库入门 通用类

DBMS_SCHEDULER执行PERL脚本加载数据

1.例子利用oracle 11g 的dbms_scheduler包执行perl脚本加载数据文件,其中主要用到三个过程分别为SET_JOB_ARGUMENT_VALUE,CREATE_JOB,RUN_JOB三个过程,其中三个过程的参数说明如下: create_job参数: Attribute Description job_name Name of the job job_class Name of the job class job_style Style of the job: REGULAR

[Pytorch]Pytorch 保存模型与加载模型(转)

转自:知乎 目录: 保存模型与加载模型 冻结一部分参数,训练另一部分参数 采用不同的学习率进行训练 1.保存模型与加载 简单的保存与加载方法: # 保存整个网络 torch.save(net, PATH) # 保存网络中的参数, 速度快,占空间少 torch.save(net.state_dict(),PATH) #-------------------------------------------------- #针对上面一般的保存方法,加载的方法分别是: model_dict=torch.

第一章 CLR的执行模型

概念篇 CLR(Common Language Runtime)[公共语言运行时] 可由多种编程语言使用的运行环境,提供内存管理.程序集加载.安全性.异常处理和线程同步等支持. CTS(Common Type System)[通用类型系统] 规范化的类型定义和管理,比如:字段.方法等, 又比如继承等特性. CLS(Common Language Specification)[公共语言规范] 针对CLR/CTS定义的最基本的组建. Manuged Module[托管模块] 标准的32位Mircor

01.CLR的执行模型

在非托管的C/C++中,可以进行一些底层的操作 "公共语言运行时"(CLR)是一个可由多种编程语言使用的"运行时" CLR的核心功能包含: 内存管理 程序集加载 安全性 异常处理 线程同步 可由支持CLR的编程语言编写源代码,再由对应的编译器检查语法和分析源代码,最后都会生成托管模块,托管模块需要CLR才能执行 托管模块的组成: PE32或PE32+头:包含与本地CPU代码相关信息 CLR头:托管模块的头信息,包含CLR版本,一些标志等 元数据:元数据表,包含源代码

【C#进阶系列】01 CLR的执行模型——一个Hello World的故事

好吧,废话少说,先上一章Hello World图: 我们有了一个Hello world程序,如此之简单,再加上我今天没有用汉字编程o(>﹏<)o,所以一切很简单明了. 故事开始: 编译: 一个程序写完肯定要编译,以前什么C啊什么的都是编译成本机的CPU指令,但是我们的C#不是. C#,VB.NET都会把它们编译成托管模块,托管模块在一个标准的可移植的PE文件中.(那些懵懂的少年肯定慌了,这是什么鬼,又是托管模块又是PE文件的.莫慌,所有你听不懂的高大上的术语其实都很简单,你现在不需要懂,听我慢

第一章、 CLR的执行模型

1. 概述 本章主要是介绍从源代码到可执行程序的过程中,CLR所做的工作. 2. 名词解释 ① 公共语言运行时(Common Language Runtime, CLR),是一个可由多种语言使用的 运行时,核心功能(内存管理.程序集加载.安全性.异常处理和线程同步)可由面向CLR的所有语言使用. ② PE32:32位 Microsoft Windows 可移植执行体.    PE32+:64位 Microsoft Windows 可移植执行体. ③ 元数据 是一组数据表,这些数据表描述了 模块中

第1章CLR的执行模型1.1

1.1将源代码编译成托管代码模块 如上图,用支持CLR的任何一种语言来创建源代码文件.再用一个对应的编译器来检查语法和分析源代码.经编译器编译后生成托管模块(managed module),它是一个可移植执行体文件,它可能是32位(PE32)文件,也可能是64位(PE32+)文件.托管模块包括中间语言和元数据,需要CLR才能执行. 公共语言运行时(Common Language Runtime, CLR)是一个供多种编程语言使用的运行时.可用任何编程语言来开发代码,只要编译器是面向CLR的就行.

CLR的执行模型

1,将源代码编译成托管代码.源代码如C#,VB,F#2,将托管代码合并成程序集.3,加载公共语言运行时.4,执行程序集的代码.