DLL 是动态链接库,在运行时被链接。一个系统中有不同语言的dll,如C++、c、.net等。我的问题是操作系统如何区分.net dll和其他dll?
例如,如果我在 C++ 中创建了 a.dll 并在 C#.net 中创建了 a.dll,那么现在在 .net 项目中我指的是 a.dll(C#)。操作系统将如何区分引用两者的 a.dll(C#) 和 a.dll(C++) 进程正在运行。
DLL 是动态链接库,在运行时被链接。一个系统中有不同语言的dll,如C++、c、.net等。我的问题是操作系统如何区分.net dll和其他dll?
例如,如果我在 C++ 中创建了 a.dll 并在 C#.net 中创建了 a.dll,那么现在在 .net 项目中我指的是 a.dll(C#)。操作系统将如何区分引用两者的 a.dll(C#) 和 a.dll(C++) 进程正在运行。
Windows 使用Portable Executation Format
.Net DLL 和可执行文件。该 Wiki 文章的摘录:
Microsoft 的 .NET Framework 已通过支持公共语言运行时 (CLR) 的功能扩展了 PE 格式。新增内容包括 CLR 标头和 CLR 数据部分。加载二进制文件后,OS 加载程序通过 PE/COFF IMPORT 表中的引用将执行交给 CLR。然后 CLR 加载 CLR Header 和 Data 部分。
CLR 数据部分包含两个重要段:元数据和中间语言 (IL) 代码:
元数据包含与程序集相关的信息,包括程序集清单。清单详细描述了程序集,包括唯一标识(通过哈希、版本号等)、导出组件的数据、广泛的类型信息(由通用类型系统 (CTS) 支持)、外部引用和文件列表大会内。CLR 环境广泛使用元数据。
中间语言 (IL) 代码是抽象的、与语言无关的代码,它满足 .NET CLR 的通用中间语言 (CIL) 要求。术语“中级”是指 IL 代码的跨语言和跨平台兼容的性质。这种中间语言,类似于 Java 字节码,允许平台和语言支持通用的 .NET CLR。IL 支持面向对象的编程(多态、继承、抽象类型等)、异常、事件和各种数据结构。
该文章的相关摘录:
为 Microsoft .NET 环境生成的可执行文件首先是 PE 文件。但是,在大多数情况下,.NET 文件中的正常代码和数据很少。.NET 可执行文件的主要目的是将 .NET 特定信息(例如元数据和中间语言 (IL))放入内存。
此外,.NET 可执行文件链接到 MSCOREE.DLL。此 DLL 是 .NET 进程的起点。加载 .NET 可执行文件时,它的入口点通常是一小段代码。该存根只是跳转到 MSCOREE.DLL(_CorExeMain 或 _CorDllMain)中的导出函数。从那里,MSCOREE 负责,并开始使用可执行文件中的元数据和 IL。
此设置类似于 Visual Basic(.NET 之前)中的应用程序使用 MSVBVM60.DLL 的方式。.NET 信息的起点是 IMAGE_COR20_HEADER 结构,目前在来自 .NET Framework SDK 的 CorHDR.H 和更新版本的 WINNT.H 中定义。IMAGE_COR20_HEADER 由 DataDirectory 中的 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 条目指向。
它谈论可执行文件,但 PE 格式也用于 .Net DLL。
有关详细信息,请参阅文章本身。如您所见,这些东西并不简单!
操作系统从不涉及。DLL 种类的托管程序集由 Assembly.Load() 和朋友加载。抖动编译代码时根据需要隐式显示。或者当您在代码中使用其中一种 Assembly.Load 变体时明确表示。
唯一涉及操作系统的时间是在启动 EXE 时。更高版本的 Windows 版本(XP 和更高版本)确实具有托管 EXE 的意识。确切的机制没有记录,除了 mscoree.dll 是一个重要的播放器之外,它充当加载程序的存根,并且是实际加载 CLR 的帮助程序 DLL。Windows 会自动加载它,大概是通过它看到可执行文件中的 CLR 标头。
旧的 Windows 版本(Windows 98 和 2000)没有这种意识,EXE 包含 5 个字节的非托管代码。只是跳转到 mscoree.dll 中的 _CorExeMain() 函数。然后它完成了加载 CLR 的正常工作。由于 32 位 EXE 可以作为 64 位进程执行的不寻常功能,操作系统需要参与到以后的版本中。即时修改可执行文件以创建 64 位进程所涉及的 hackorama 非常复杂。