NET框架程序设计-第1章.NET框架开发平台体系架构

news2025/2/28 19:58:15

1.1 .NET 框架基本组成

.NET 框架的核心便是通用语言运行时(Commomn Language Runtime,简称 CLR),CLR 是一个可被各种不同的编程语言所使用的运行时。
托管模块(mangaed module): 一个需要 CLR 才能执行的标准 Windows 可移植可执行(porttable executable ,简称 PE)文件。

将源代码编译为托管模块:
请添加图片描述

表1-1 描述了一个托管模块的各个组成部分
请添加图片描述

托管代码:由于生存期和执行行为受 CLR 管理的缘故,IL 代码有时也称作托管代码
元数据:为托管模块产生完整的元数据。一个数据表的集合。一些用于描述托托管模块中所定义的内容(比如所定义的类型和它们的成员),另外还有一些用于描述托管模块中所引用的内容(比如被引用的类型和它们的成员)。元数据是一些早先的技术如类型库、接口定义语言(IDL)文件的一个超集(CLR 元数据包括但不仅限于列举出来的文件)。

编译器同时产生元数据和 IL 代码,并且总是同时将它们嵌入到生成的托管模块中。

元数据有很多用处,比如:

  • 元数据省去了源代码编译时对头文件和库文件的需求,这是因为在含有实现类型和成员的 IL 代码文件中,已经包含了所有被引用的类型和成员的信息。编译器可以直接从托管模块中读取元数据来获得这些信息。

  • Visual Studio .NET 可以利用元数据来辅助我们编写代码。它的智能感知(IntelliSense)特性就是通过分析元数据来告诉我们某个类型提供了哪些方法,以及某个方法有哪些参数。

  • CLR 的代码验证过程可以利用元数据来确保代码仅执行“安全”的操作

  • 利用元数据,我们可以将一个对象的字段序列化到一个内存块中,然后远程传送给另一台机器,最后再在远程机器上执行反序列化,从而重新创建对象和它的状态

  • 利用元数据,垃圾收集器可以追踪对象的生存期。对于任何对象,垃圾收集器都能够通过元数据来确定该对象的类型,并且可以获知该对象的哪些字段引用了其他对象。

微软的C++ 编译器默认生成的是非托管模块,但可以通过指定一个新的命令行开关,C++ 编译器也能够产生处需要 CLR 才能执行的托管模块。

1.2 将托管模块组合为程序集

CLR 实际上并不和托管模块打交道,它直接打交道的对象是程序集(assembly)。
程序集:一个或多个托管模块,以及一些资源文件的逻辑组合。程序集是组件复用,以及实施安全策略和版本策略的最小单位

图1-2 将托管模块组合为程序集
请添加图片描述

PE 文件(托管模块):包含了一个称作清单(manifest)的数据块。所谓清单仅仅是另外一些元数据表的集合。这些表描述了组成程序集的文件,程序集所有文件中实现的共有导出类型,以及一些和程序集相关的资源文件或数据文件。
托管模块与程序集

  • 仅包含以管模块、并且没有资源(或者数据)文件,程序集就是托管模块。程序集中的模-
  • 块还包含它所引用的程序集的一些信息(如版本号信息)。它不需要再在注册表或者活动目录(Active Directory)中获取额外的信息。因此,程序集的部署要比非托管组件的部署容易得多。

1.3 加载通用语言运行时

判断机器中是否安装了 .NET 框架:

  • 通过在 %windir%\system32 目录下查找 MSCorEE.dll 文件来判断。(…\Windows\System32 目录下)
    判断机器中安装了哪些版本的 .NET 框架:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramewirk\policy

启动应用程序:
当生成一个 EXE 程序集时,编译器/链接器会产生一些特殊的信息,并将它们嵌入到结果程序集的 PE 文件表头及其各个组成文件的 .text 部分。当 EXE 文件被调用时,这些特殊的信息将导致 CLR 被加载并初始化。 CLR 随后会定位到应用程序的入口点方法,从而以此来启动应用程序。

图1-3 加载并初始化 CLR
请添加图片描述

MSCorEE.dll 表示为微软组件对象运行时执行引擎。

托管应用程序启动:
当编译器/链接器创建一个可执行程序集时,x86 stub 函数 JMP CorExeMain 被嵌入到PE文件里。
CorExeMain 函数 从 MsCorEE.dll 动态链接库中导入的,所以 MsCorEE.dll 将在程序集文件的导入==(.idata)==部分被引用。

执行过程:

  • 1、当托管 EXE 文件被调用时,Windows 将像对待通常(即非托管)的 EXE 文件一样来对待它。

  • 2、Windows 加载器首先加载该EXE文件,然后检查其 .idata 部分发现 MSCoreEE.dll 需要被加载到进程的地址空间,于是加载器获取 MSCoreEE.dll 中 __CoreExeMain 函数地址,同时修正托管 EXE 文件中 stub 函数的 JMP 指令

  • 3、进程的主线程开始执行修正后的 x86 stub 函数,该 stub 函数立即跳转到 MSCorEE.dll 中的_CorExeMain 函数上。

  • 4、_CorExeMain 函数接着初始化 CLR,并查看可执行程序集的 CLR 表头以确定要执行的托管入口点方法。

  • 5、入口点方法找到后,其 IL 代码随之被编译为本地 CPU 指令

  • 6、最后,CLR 跳转到编译后的本地指令上(使用进程的主线程)。

  • 7、这时,托管应用程序才算开始真正运行

托管 DLL 执行:
编译器/链接器将会为 DLL 程序集 PE文件的 .text 部分产生一个类似 x86 stub 函数: JMP __CorDllMain。
_CorDllMain 函数 从 MsCorEE.dll 动态链接库中导入的,所以 托管DLL 中的 (.idata)部分 也包含有对MSCorEE.dll 的引用。

执行过程:

  • 1、当 Windows 加载托管 DLL 时,它将自动加载 MSCorEE.dll(如果它还没有被加载)。

  • 2、然后获取 _CorDllMain 函数的地址,并修正托管 DLL 中 x86 stub 函数的 JMP 指令。

  • 3、之后,调用 LoadLibrary 加载托管 DLL 的线程将跳转到该托管 DLL 中的x86 stub 函数上。(非托管代码加载托管 DLL 步骤)
    托管代码调用托管 DLL: 首先检测托管 DLL 中的元数据,然后便以即时编译的方式执行其内方法的 IL 代码,stub 函数及其跳转过程被忽略)

  • 4、该 stub 函数接着又立即跳转到 MSCorEE.dll 中的 _CorDllMain 函数上。

  • 5、_CorDllMain 初始化 CLR(如果 CLR 还没有为该进程初始化)后便立即返回。(非托管代码加载托管 DLL 步骤)

  • 6、应用程序也返回到正常状态并继续运行。

注意:托管 PE 文件总是使用 32 位的 PE 文件格式。在64位的 Windows 系统上,操作系统加载器检测到 32 位的托管 PE 文件后会自动创建64位的地址空间。

1.4 执行程序集代码

IL 代码的作用:理解对象类型,并且拥有很多高级的指令,这些指令可以创建和初始化对象,调用对象上的虚方法,以及直接操作数组元素。它甚至还有抛出和捕获异常的指令。
IL 汇编器:ILAsm.exe
IL 反汇编:ILDasm.exe

即时(just-in-time)编译器执行内容:执行一个方法,它的 IL 代码还必须首先被转换成本地 CPU 指令。

方法的第一次调用:
请添加图片描述

执行过程:

Main函数第一次调用:

  • 1、在 Main 方法执行之前,CLR 首先会检测 Main 中代码引用到的所有类型。这会导致 CLR 分配一个内部的数据结构。该数据结构用于管理对所引用到的类型的访问。(比如为 Console 分配一个单独的内部结构)

  • 2、在这里内部的数据结构中, Console 类型中定义的每一个方法都会有一个对应的条目,每个条目中将保存有一个方法实现代码的地址。

  • 当该数据结构被初始化时,CLR 将==把每一个条目设置为 ==CLR 内部的一个没有正式记录的函数:JITCompiler。

  • 当 Main 方法第一个调用 WriteLine 时, JITCompiler 函数将被调用,该函数负责将一个方法的 IL 代码编译成本地 CPU 指令。因为 IL 代码是被“即时(just-in-time)”编译的,所以 CLR 的这一部分通常被称作 JITter 或者即时编译器。(JIT compiler)

  • 当 JITCompiler 函数被调用时,它会知道正在调用的是哪个方法,以及该方法是由哪个类型定义的。

  • JITCompiler 函数随后会在被调用方法所定义的程序集中的元数据内搜索其 IL 代码的位置

  • JITCompiler 接着验证这些 IL 代码并将编译成本地 CPU 指令。这些本地 CPU 指令将被保存在一个动态分配的内存块中

  • 然后 JITCompiler 将前面内部数据结构中被调用方法的地址替换为包含本地 CPU 指令的内存块地址。

  • 最后 JITCompiler 将跳转到该内存块中的代码上。这里的代码就是 WriteLine 方法的实现代码。当该代码执行完毕,它将返回到 Main 函数中,Main 函数会接着继续执行下面的代码。

Main 函数第二次调用:

  • 1Main 函数开始第二次调用 WriteLine。由于 WriteLine 中的 IL 代码已经被验证并且编译过,所以这一次将直接调用内存块中已有的本地代码,完全跳过 JITCompiler 函数的验证和编译过程。
  • 在 WriteLine 方法执行之后,同样将返回到 Main 中。

请添加图片描述

1.4.1 IL与代码验证

IL 是一种基于堆栈的语言。意味着它的所有指令或者是将操作数推进一个执行堆栈中,或者从堆栈中弹出结果。
IL 指令是无类型的。
当 IL 代码被编译为本地 CPU 指令时,CLR 将执行一个称作验证的过程。验证过程检查高级 IL 代码,确保它做的每件事都是”安全“的。

验证过程可以验证的情况:

  • 不能从未初始化的内存中读取数据;
  • 每个方法调用都必须传入正确的参数个数,并且各个参数的类型要正确匹配;
  • 每个方法的返回值都必须被正确地使用;
  • 每个方法都必须有一个返回语句;

托管代码的好处:

  • 通过验证托管代码,确保它们不会访问它们不应该访问的内存,因此也就不会干扰另一个应用程序的代码。
  • 在一个操作系统进程中运行多个托管应用程序可以减少进程的数量,从而提高系统性能,降低资源需求。

应用程序域: CLR 提供了在一个单独的操作系统进程中执行多个托管应用程序的能力。在 CLR 中,一个托管应用程序称作一个应用程序域。

默认情况下,一个托管 EXE 仅执行在它自己单独拥有的地址空间中(该地址空间中仅含有一个因公用程序域)。到那时,CLR 的宿主进程可以决定在一个操作系统进程中运行多个应用程序域。

1.5 .NET 框架类库

.NET 框架包括 .NET 框架类库(Framework Class Library,简称 FCL)程序集
.NET 应用程序:

  • XML Web 服务: XML Web Services。涉及的内容,HTTP,SOAP,XML,用来
  • Web 窗体:Web Forms。一种基于 HTML的应用程序(Web 站点),涉及的内容,ASP.Net。
  • Windows 窗体:Windows Forms。
  • Windows 控制台应用程序。
  • Windows 服务:由 Windows 服务控制管理器(Service Control Manager,简称 SCM)控制的服务程序。
  • 组件库。
命名空间描述
System其中的类型是为所有应用程序使用的一些基本类型
System.Collection其中的类型用于管理对象集合。包括常用的集合类型,例如堆栈、队列、散列表等
System.Diagnostics其中的类型用于帮助诊断和调试应用程序
System.Drawing其中的类型用于操作二维图形。它们典型地用于 Windows 窗体应用程序,以及创建 Web 窗体页面中显示的图像
System.EnterpriseServices其中的类型用于管理事务、队列组件、对象池、JIT 激活(JIT特指 COM+ 组件服务,即 .NET 内的企业服务中对象的即时激活技术)、安全以及其他一些提高服务器程序中托管代码效能的特性
System.Globalization其中的类型用于多国语言支持(National Language Support,简称 NLS),例如字符串比较、格式化以及日历功能
System.IO其中的类型用于操作 I/O 流、遍历目录和文件
System.Management其中的类型通过 Windows 管理设备(Windows Management Instrumentation,简称 WMI)来管理企业中的计算机
System.Net其中的类型用于网路通信
System.Reflection其中的类型用于查看元数据以及延迟绑定类型和它们的成员
System.Resources其中的类型用于操作外部数据资源
System.Runtime.InteropServices其中的类型允许托管代码访问非托管操作系统平台中的一些功能,如 COM 组件和 Win32 DLL 内的函数
System.Remoting其中的类型用于从远程机器上访问类型
System.Serialization其中的类型用于持久化(persist)对象实例,以及一个流(stream)中重新产生对象实例
System.Security其中的类型用于保护数据和资源
System.Text其中的类型用于以不同的编码方式(如 ASCLL 或者 Unicode)来操作文本
System.Threading其中的类型用于异步操作,以及同步访问资源
System.Xml其中的类型用于处理 XML 模式(schema)和数据
System.Web.Services其中的类型用于创建 XML Web 服务
System.Web.UI其中的类型用于创建 Web 窗体
System.Windows.Forms其中的类型用于创建 Windows GUI 应用程序
System.SeviceProcess其中的类型用于创建由 SCM 控制的 Windows 服务

1.6 通用类型系统

通用类型系统(Common Type System,简称 CTS)来描述类型的定义和行为,包括:字段、方法、属性、事件

CTS还定义了类型可见性和访问类型成员的一些规则,访问控制如下:

  • Private:方法(此处本书只提到方法,但其他成员如字段也是此规则的吧?)只能被同一类型中的其他方法调用。
  • Family:方法可以被派生类型中的代码调用。而不管它们是否位于同一个程序集。(即 protected)
  • Family 与 assembly:方法只可以被位于同一个程序集中的派生类型中的代码调用。IL 汇编语言有这种访问控制,但C# 和其他一些编程语言不支持
  • Assembly:方法可以被同一个程序集中的任何代码调用。(即 internal)
  • Family 或 assembly:方法可以被任何程序集中的派生类型的代码调用,也可以被同一程序集中的任何类型调用。 C# 将之称为 protected internal。
  • Public:方法可以被任何程序集中的任何代码调用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/581587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实验 3:图形数据结构的实现与应用

东莞理工学院的同学可以借鉴,请勿抄袭 1.实验目的 通过实验达到: 理解和掌握图的基本概念、基本逻辑结构; 理解和掌握图的邻接矩阵存储结构、邻接链表存储结构; 理解和掌握图的 DFS、BFS 遍历操作的思想及其实现; …

威胁情报如何改进 DDoS 保护

分布式拒绝服务 (DDoS) 攻击已成为各种企业的主要威胁,从最小的跨国公司到最大的跨国公司。 根据 2022年全球威胁分析报告,恶意DDoS攻击较2021年增长了150%。此外,DDoS攻击的频率也出现显着上升,令人担忧。 在全球范围内&#x…

港大、南大、清华抢先开源「复刻」版DragGAN,开箱即用!

来源 |新智元 还记得前几天发布的DragGAN吗? 没错,就是那个「轻轻点两下」1秒修图的工具。 ▲拍的照片表情不好?修!脸型不够瘦?修!脸冲镜头的角度不对?修! ▲搞不好,「让…

https 建立连接过程分析

从真实的抓包开始 根据抓包结果可以看到 从客户端发起请求开始,主要经过以下几个过程: 1、TCP 三次握手 2、浏览器发送 Client Hello 到服务器 3、服务器发送Server Hello 、证书、证书状态、服务端密钥交换,到浏览器 4、浏览器发送 客户端密…

【Linux】搭建SFTP文件服务器

一、协议介绍1.1 FTP 协议1.11 特点1.12 基本工作原理 1.2 SFTP协议1.21 特点1.22 基本工作原理 1.3 ssh协议1.31 特点1.32 基本工作原理 1.4 其他常见文件传输协议 二、搭建Linux的SFTP文件服务器三、连接测试3.1 电脑连接3.2 手机连接 一、协议介绍 1.1 FTP 协议 1.11 特点…

chatgpt赋能python:Python如何实现不换行

Python如何实现不换行 Python是一种高级编程语言,它的应用领域非常广泛,尤其是在数据分析、人工智能、网络爬虫等领域中拥有广泛的应用。而在Python中,有时候需要控制输出内容的样式,比如在输出时避免出现换行,这个需…

Bootstrap中的js插件使用

1. 标签页 1.1 init <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevic…

sqli_labs21-23

less21 这题是cookie注入&#xff0c;如果不登录进去是看不到cookie信息的&#xff0c;所以我们要先登录进去 用户admin&#xff0c;密码admin 抓包后发现cookie字段有base64编码信息&#xff0c;选中后burp自动检测翻译 既然是cookie注入并且字段是被加密了的&#xff0c;说明…

chatgpt赋能python:Python中5/2问题引发的思考

Python中5/2问题引发的思考 在Python中&#xff0c;我们常常遇到数字计算的问题&#xff0c;比如5/2。当我们在Python中执行如下代码时&#xff1a; print(5/2)输出结果为2.5。 但是在其他编程语言中&#xff0c;比如C和Java&#xff0c;同样的计算结果是2&#xff0c;而不是…

chatgpt赋能python:Pythonnumpy库下载教程:学习数据分析必备工具

Python numpy库下载教程&#xff1a;学习数据分析必备工具 介绍 Python是一种优秀的脚本语言&#xff0c;常用于数据分析、机器学习等领域&#xff0c;而Numpy是Python中最基础的科学计算库&#xff0c;提供了大量针对数组及矩阵操作的函数和方法。然而&#xff0c;对于初学者…

jQuery元素操作和尺寸位置

1. 遍历元素 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width,…

Kubernetes_核心组件_kubelet_kubelet服务全解析

文章目录 前言一、查看kubelet当前运行1.1 查看kubelet当前运行1.2 kubelet配置文件1.3 kubelet启动参数文件1.4 kubelet启动全过程 (自定义启动参数文件) 二、kubelet启动过程2.1 kubelet启动过程2.2 自定义kubelet所有文件并运行步骤1&#xff1a;新建静态token文件和user&am…

Fourier分析入门——第11章——Fourier变换

目录 第11章 Fourier变换(Transform) 11.1 引言 11.2 逆向正弦和余弦变换(The Inverse Cosine and Sine Transforms) 11.3 正向正弦和余弦变换(The Forward Cosine and Sine Transforms) 11.4 离散谱对比谱密度(Discret spectra vs. spectral density) 11.5 Fourier变换的…

chatgpt赋能python:Python中4.5/2等于多少?——解密Python的除法运算

Python中4.5/2等于多少&#xff1f;——解密Python的除法运算 Python作为一种常用的编程语言&#xff0c;在业界有着广泛的应用。而除法是Python中常用的运算之一。但是&#xff0c;当我们输入4.5/2时&#xff0c;会得到什么样的结果呢&#xff1f;这篇文章将解密Python的除法…

Spring Boot:从入门到实践的全面指南

文章目录 1. Spring Boot简介及特性1.1 简介&#xff1a;什么是Spring Boot1.2 特性&#xff1a;Spring Boot的优势与特点1.3 四大核心&#xff1a;Spring Boot的核心组成 2. Spring Boot入门案例2.1 Spring Boot项目开发步骤2.2 创建一个Spring MVC的Spring Boot Controller2.…

chatgpt赋能python:Python不能参加奥赛的原因

Python不能参加奥赛的原因 Python 是一种广泛使用的高级编程语言&#xff0c;以其简单易学、可读性高等特点受到了众多程序员的喜爱&#xff0c;但是它在国际奥林匹克竞赛中并不被允许参赛。本文将会介绍 Python 不能参加奥赛的原因&#xff0c;并且分析该限制是否合理。 原因…

使用 GitHub Actions 自动部署 Hexo 个人博客

文章目录 申请 GitHub Token源码仓库配置 Github Action重新设置远程仓库和分支查看部署 每次部署 Hexo 都需要运行 hexo cl & hexo g & hexo d 指令三件套完成推送到远程仓库&#xff0c;随着文章越来越多&#xff0c;编译的时间也会越来越长&#xff0c;通过 Github …

前缀树概念

前缀树&#xff08;prefix tree&#xff09; 准备一个Str[]&#xff0c;数组中元素有[“abc”,“bcd”,“abg”,“bcde”,“qwe”]&#xff0c;如何将数组中元素加到树中呢&#xff1f; 从最开始的字符串abc说&#xff0c;第一个字符是a&#xff0c;从一个空的头节点出发&#…

jQuery属性操作和内容文本值

1. 属性操作 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width,…

全局CSS样式1

1. 响应式基础 1.1 init <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv"X-UA-Compati…