0

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++) 进程正在运行。

4

2 回答 2

2

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 支持面向对象的编程(多态、继承、抽象类型等)、异常、事件和各种数据结构。

这是一篇讨论可移植执行格式的 MSDN 文章。

这是该文章的第 2 部分。

该文章的相关摘录:

为 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。

有关详细信息,请参阅文章本身。如您所见,这些东西并不简单!

于 2013-06-16T09:01:16.350 回答
1

操作系统从不涉及。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 非常复杂。

于 2013-06-16T09:40:09.900 回答