.NET dll和普通dll之间的`确切`区别是什么?

35

我想知道.NET dll和普通dll之间的确切区别。第一个问题是,“普通”DLL被称为什么?我使用“normal”这个词,但似乎不太对?

因为两者都遵循PE格式。是的,我同意.NET DLL有一个额外的部分。除此之外其他方面都是相同的。

我还知道,在.NET中,代码被转换为CIL / MSIL,那么填充在PE文件的.text部分中的是什么?MSIL?因为没有二进制代码。但如果他们将MSIL放在.text部分。加载器会认为它是二进制代码并允许其执行。但事实并非如此。我错过了什么吗?

我很惊讶知道:

即使DLL文件扩展名是人为的。您可以使用完全不同的扩展名来创建DLL - 例如OCX控件和控制面板应用程序(.CPL文件)都是DLL。

还有哪些扩展名可用于DLL文件?

但我可以理解为什么要使用不同的扩展名。为什么在.NET DLL的情况下没有这样做?他们本可以使用新扩展名来将其与“正常”的DLL区分开来。他们甚至为.NET中的DLL使用了不同的名称(ASSEMBLY),但没能更改扩展名。哎?

另一个完全不同的问题:什么是DLL注册?他们使用regsvr32.exe进行注册。对吧?我在安装Windows XP SP3后注意到它。在安装后,在重启Windows之前,我检查了启动列表,并发现了许多带有许多DLL的regsvr32.exe条目。

请随意深入研究。我正在学习有关链接器、加载器和二进制格式的知识。我熟悉PE文件格式。


文件格式是PE,带有一个新的节。我对二进制和MSIL代码感到困惑。它们应该放在哪里?.text节中会有什么?每个部分应该放置在哪里等等... - Buttler
3
@Randy - 这个链接根本没有回答这里所问的问题。此外,立即将别人引导到Google也是不被赞同的。 - John Rasch
我给你点赞 - 很好的问题,很有趣! :) - t0mm13b
你不需要使用regsvr32来注册.NET dll/exe,因为CLR本身就是一个COM服务器 :o) - Chris S
这句话的意思是:“你不需要使用regsvr32来注册.NET dll/exe,因为CLR本身就是一个COM服务器。” - Buttler
4个回答

15
我从我的博客复制并粘贴了以下内容: .NET dll的格式如下: PE头 CLR头 CLR元数据 CLR IL代码 本机数据
PE头是所有Win32应用程序和库所具有的一个可移植可执行文件头,它指示Windows如何处理文件。对于.NET程序集,这将加载CLR,然后CLR再加载程序集。
CLR头包含信息,例如.exe或程序集所编写的.NET版本,任何强名称签名哈希值,可以在其中找到资源的文件中的地址(RVA或相对虚拟地址)以及最重要的应用程序入口点,它是指向MethodDef元数据表或另一个文件的标记。对于类库,此标记为0。
CLR元数据是关于模块的信息,存储在几种不同类型的“流”内。这些流通常是压缩的,除了可以进行编辑和继续使用的#~。这些流分为两种形式:堆只用于存储,表格用于存储各种DLL/程序集的不同部分 - 例如,所有类型都存储在TypeRef表格中,所有方法都在Method表格中。每个表格引用父表格。
表格的起始点是仅包含模块名称和GUID的Module表的一个单独行。在此之后是ModuleRef表,其中包含有关此模块所引用的所有模块(来自同一程序集)的信息。在VS.NET及其对csc.exe的使用中,程序集中没有多个文件,只有一个模块。

接下来是TypeDef表,其中包含6个列,分别为类型名称、命名空间、其父级(接口和Object为0),字段在FieldDef表中的起始行、方法在MethodDef表中的起始行。

IL和本地数据

应用程序本身。

如果您感兴趣,《深入解析Microsoft .NET IL汇编器》-Serge Lidin一书会更详细地介绍。


5
这是一个好问题。对于.NET DLL和普通DLL,有一个关键的区别,为了本回答,让我们使用术语native DLL作为不依赖于.NET框架的普通DLL。
关键的区别在于.NET PE头布局中有第15个数据目录条目,而本地DLL只有14个数据目录条目。这就是你可以区分两者的方法,对于本地DLL,该条目将为零!而且不仅如此,.NET DLL将嵌入元数据供框架处理,例如请求安全权限的属性等,.NET EXE也适用。
与伪装成DLL的不同扩展名(如OCX和CPL)相关的屏幕保护程序是另一种非DLL扩展名的例子,从.EXE的角度来看,即那些.SCR实际上是.EXE。尽管听起来很奇怪,但似乎微软制作了一些应用程序来使用特定的扩展名作为EXE和DLL,我认为这是Windows 3.1时代的遗留,CPL用于控制面板,OLE称为对象链接和嵌入到OCX现在是ActiveX,SCR用于屏幕保护程序,也就是.EXE。如果相同的情况适用于.MSCc(Microsoft Snap In Consoles中使用的服务扩展名),那么这并不奇怪。
DLL注册是指regsvr32注册DLL及其类ID,可以在注册表的HKEY_CLASSES_ROOT键下找到这些信息,这更可能是用于COM(组件对象模型),以使COM对象对所有语言具有全局可见性,而不考虑开发语言/环境。ActiveX DLL也适用于同一类别,其中一些已知会自动注册自己(包括COM DLL),包括它们的类型库标识符(typelib id's)...
在Windows 95之前,许多软件都有自己的DLL散落在各处,有些是重复的,我记得最常见的是CTL3D.DLL(还记得吗?那会让Windows控件看起来有3D效果-天哪!)。到处都有很多版本的它,这种重复和版本差异将导致Windows 95中出现的DLL地狱。当时,注册表首次亮相,旨在通过将所有类型库注册在一个位置而不是在各处复制DLL来解决DLL地狱问题,但当时并没有解决版本问题,导致程序看起来损坏,因为由DLL使用的类ID被替换为新的DLL版本,导致程序崩溃!

没有 *.msc 文件不是 PE 文件。令人惊讶的是,它们是 XML 文件。是的,我已经检查过了。尝试在记事本中打开 "C:\WINDOWS\system32\compmgmt.msc"、"C:\WINDOWS\system32\diskmgmt.msc" 等文件。 :) - Buttler
当我们在运行或命令提示符中键入diskmgmt.msc并按下回车时,我想知道命令行是如何转换为:"C:\WINDOWS\system32\mmc.exe" "C:\WINDOWS\system32\diskmgmt.msc"。 - Buttler
1
@Buttler:这只是标准的Windows魔法。就像输入mydocument.doc然后Word打开一样。扩展名为.msc的文件通过HKCR\.mscHKCR\mscfile注册表键映射到mmc.exe以打开它们。 - Dirk Vollmar
1
@Buttler:我同意divo的观点。这就是如何调用某些程序,注册表中有“扩展处理程序”,根据扩展名(.doc、.scr、.msc)确定要使用哪个应用程序打开。没有什么魔法可言... - t0mm13b

1

普通DLL

.dll文件包含编译代码,您可以在应用程序中使用它来执行特定的程序功能,并且可能需要另一个应用程序或模块(例如.exe或.dll)通过入口点加载它。

.Net DLL

当您在.NET语言(如C#或VB.NET)中实现.Net DLL(程序集)时,您会生成托管程序集。 托管程序集是由.NET指定的组件标准。 因此,.Net程序集只能被Microsoft.NET理解,并且只能在.NET托管应用程序中使用。

更多信息.... 普通DLL和.Net DLL之间有什么区别?

Matt


0

其他答案中没有提到的是,c/c++ '.dll' 文件只是一种命名约定 - 你可以随便叫它什么,因此也有 .ocx 和 .cpl。
c/c++ dll 是一组代码和数据,在运行时使用 LoadLibrary 加载并映射到被调用者的地址空间。它仍然编译为本机代码,但没有任何关于目标地址空间的概念,因为它被设计成由加载器进行修补和修复。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接