第 12 章 装配 装配
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
在本书中,我一直用组件来描述库或可执行文件。现在是时候更仔细地研究一下它的确切含义了。在 .NET 中,软件组件的正确术语是程序集,它通常是一个.dll或.exe文件。有时,程序集会被分割成多个文件,但即便如此,它仍然是一个不可分割的部署单元--你必须将整个程序集提供给运行时,否则就根本不用部署它。程序集是类型系统的一个重要方面,因为每个类型不仅由其名称和命名空间标识,还由其包含的程序集标识。与单个类型相比,程序集提供了一种更大规模的封装,这要归功于在程序集级别工作的internal 可访问性规范器。
运行时提供了一个程序集加载器,可自动查找和加载程序所需的程序集。为确保加载器能找到正确的组件,程序集具有包含版本信息的结构化名称,并可选择包含全局唯一元素,以防止歧义。
在 Visual Studio 中,"创建新项目 "对话框中的大多数 C# 项目类型都会生成一个程序集作为主要输出。它们通常还会在输出文件夹中放入其他文件,如项目所依赖的未内置到 .NET 运行时的任何程序集的副本,以及应用程序所需的其他文件。(例如,网站项目除了服务器端代码外,通常还需要生成 CSS 和脚本文件)。但通常会有一个特定的程序集作为项目的构建目标,其中包含项目定义的所有类型以及这些类型所包含的代码。
装配剖析
程序集使用 Win32Portable Executable (PE) 文件格式,与可执行文件 (EXE) 和动态链接库 (DLL) 在现代 Windows 版本中一直使用的格式相同。1它的 "可移植性 "是指在不同的 CPU 体系结构中使用相同的基本文件格式。非.NET PE 文件通常是特定于体系结构的,但.NET 程序集通常不是。即使您在 Linux 或 macOS 上运行 .NET Core,它仍然会使用这种基于 Windows 的格式--为 .NET Core 或 .NET Standard 构建的程序集通常可以在所有支持的操作系统上运行,因此我们在任何地方都使用相同的文件格式。
C# 编译器的输出是一个程序集,扩展名为.dll或.exe。了解 PE 文件格式的工具会将 .NET 程序集识别为一个有效但相当枯燥的 PE 文件。CLR 本质上是将 PE 文件作为 .NET 特定数据格式的容器,因此对于传统的 Win32 工具来说,C# DLL 似乎不会输出任何 API。请记住,C# 编译为二进制中间语言 (IL),不能直接执行。Windows 在可执行文件或 DLL 中加载和运行代码的正常机制对 IL 无效,因为那只能在 CLR 的帮助下运行。同样,.NET 定义了自己的元数据编码格式,并不使用 PE 格式的本地功能来导出入口点或导入其他 DLL 的服务。
备注
.NET Core 中的 Ahead-of-Time (AoT) 编译工具可以在构建过程的稍后阶段为程序集添加本地可执行代码,但对于Ready to Run程序集(.NET Core 的 AoT 工具的输出被称为Ready to Run程序集),即使嵌入的本地代码也是在 CLR 的控制下加载和执行的,只有托管代码才能直接访问。
在 .NET Core 3.0 或更高版本中,您不会构建扩展名为.exe 的.NET 程序集。即使是生成可直接运行输出的项目类型(如控制台或 WPF 应用程序),其主要输出也是.dll。它们也会生成一个可执行文件,但不是 .NET ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access