【问题标题】:What are the `exact` differences between .NET dll and a normal dll?.NET dll 和普通 dll 之间的“确切”区别是什么?
【发布时间】:2011-01-16 14:13:40
【问题描述】:

我想知道 .NET dll 和普通 dll 之间的确切区别是什么。

第一个问题,什么是“普通 DLL”?我用的是“正常”这个词。但是好像不太对?

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

我也知道在.NET 中代码被转换为CIL/MSIL 那么PE 文件的.text 部分填充了什么? MSIL?因为没有二进制代码。但是如果他们把 MSIL 放在 .text 部分。 Loader 假定它是一个二进制代码并允许它执行。事实并非如此。我错过了什么?

我很惊讶地知道

即使是 DLL 文件扩展名也是 人造的。您可以使用 DLL 完全不同的扩展——对于 实例 .OCX 控件和 Control 面板小程序(.CPL 文件)是 DLL。

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

但我可以理解使用不同扩展的原因。在 .NET DLLS 的情况下,他们为什么不做同样的事情?他们本可以使用新的扩展来将其与“普通”DLL 区分开来。他们甚至为 .NET 中的 dll 设置了不同的名称 (ASSEMBLY),但无法更改扩展名。嗯?

另一个完全不同的问题:什么是 DLL 注册?他们为此使用 regsvr32.exe。正确的?我在安装 Windows XP SP3 时注意到了这一点。安装后&重新启动windows之前,我检查了启动列表,发现很多regsvr32.exe条目有很多DLL。

请随意深入了解您喜欢的深度。我正在学习链接器、加载器、二进制格式。我也熟悉PE文件格式。

【问题讨论】:

  • 文件格式相同。它的PE带有一个新的部分。我对二进制和 MSIL 代码感到困惑。他们去哪里? .text 部分将包含什么内容。什么去哪里等等。
  • @Randy - 该链接甚至没有远程回答这里提出的问题。最重要的是,在这里不赞成立即将某人发送到 Google。
  • +1 来自我 - 好问题,有趣! :)
  • 您没有向 regsvr32 注册 .NET dll/exe,-CLR 本身就是一个 COM 服务器 :o)
  • “您没有使用 regsvr32 注册 .NET dll/exe,- CLR 本身就是一个 COM 服务器”。这是什么意思?

标签: .net dll assemblies


【解决方案1】:

唯一要添加到发布的其他答案的是 c/c++ '.dll' 文件只是一个命名约定 - 您可以随意调用它,因此 .ocx 和 .cpl。
c/c++ dll 是一组代码和数据,在运行时使用LoadLibrary 加载并映射到被调用者的地址空间。它仍然被编译为本机代码,但没有任何关于它的目标地址空间的概念,因为它被设计为由加载程序修补和修复。

【讨论】:

    【解决方案2】:

    我已经从my own post 复制并粘贴了它:

    .NET dll 的格式为:

    • PE 标头
    • CLR 标头
    • CLR 元数据
    • CLR IL 代码
    • 原生数据

    PE 标头

    PE 标头是所有 Win32 应用程序和库都具有的可移植可执行标头,它指示 Windows 如何处理该文件。对于 .NET 程序集,这会加载 CLR,然后再加载程序集。

    CLR 标头

    这包含诸如 .exe 或程序集编写时使用的 .NET 版本、任何强名称签名哈希、文件中可以找到资源的地址(RVA 或相对虚拟地址)等信息。最重要的是应用程序的入口点,它是指向 MethodDef 元数据表或其他文件的令牌。对于类库,此标记为 0。

    CLR 元数据

    这是关于存储在几种不同类型的“流”中的模块的信息。这些流通常被压缩,除了 #~ 可以解压缩以进行编辑和继续。流有两种形式,一个仅用于存储的堆和表。

    DLL/程序集的各个部分根据它们的作用存储在不同的表中——例如,所有类型都存储在TypeRef 表中,所有方法都存储在Method 表中。每个表都引用一个父表。

    表的起点是模块表,其中仅包含模块的名称和 guid 作为单行。之后是 ModuleRef 表,其中包含有关此模块(来自同一程序集)引用的所有模块的信息。在 VS.NET 及其使用 csc.exe 的情况下,程序集中没有多个文件,只有一个模块。

    在此之后是 TypeDef 表,其中包含 6 列,其中包含类型的名称、命名空间、其父级(接口和对象为 0)、FieldDef 表中其字段的起始行、MethodDef 表中其方法的起始行.

    IL 和原生数据

    应用程序本身。

    如果您有兴趣,book Inside Microsoft .NET IL Assembler - Serge Lidin 会更详细地介绍。

    【讨论】:

      【解决方案3】:

      这是个好问题。 .NET DLL 和普通 DLL 之间有一个关键区别,为了回答这个问题,让我们使用术语本机 DLL 作为不依赖于 .NET 框架的普通 DLL。

      关键的区别在于 .NET PE 标头布局中有第 15 个数据目录条目,而原生 DLL 只有 14 个数据目录条目。这就是您如何区分两者的方法,对于本机 DLL,该条目将为零!不仅如此,.NET DLL 会在其中嵌入元数据,以便框架进行相应的处理,例如请求安全权限的属性等,这同样适用于 .NET EXE。

      相对于伪装成 DLL 的不同扩展,例如 OCX 和 CPL,屏幕保护程序是从 .EXE 角度来看的另一个非 DLL 扩展示例,即。那些 .SCR 真的是 .EXE 的......听起来很奇怪,似乎微软制作了一些应用程序来使用 EXE 和 DLL 的特定扩展名,我认为这是 Windows 3.1 时代的延续, CPL 用于控制面板,OLE 称为对象链接和嵌入到 OCX 现在 ActiveX,SCR 用于屏幕保护程序,即 .EXE。如果这同样适用于 .MSCc(Microsoft Snap In 控制台中使用的服务扩展),我不会感到惊讶

      DLL Registrations 是regsvr32 注册 DLL 的地方,它的类 ID 可以在注册表中的 HKEY_CLASSES_ROOT 键下找到,这很可能是用于 COM(组件对象模型),用于使 COM 对象对所有人全局可见语言与开发语言/环境无关。 ActiveX DLL 也属于同一类别,已知一些会自动注册自己(包括 COM DLL),包括它们的类型库标识(typelib id)...

      Windows 95 之前的很多软件,过去都有自己的 DLL,有些是重复的,我记得最常见的是 CTL3D.DLL(记得吗?这会给 Windows 控件带来 3D 外观 - 天哪!)。它的很多版本到处都是重复的,这种重复和版本差异导致了 Windows 95,被称为 DLL 地狱。它在那里,注册表在启动时首次亮相,旨在通过在一个地方注册所有类型库而不是在整个地方复制 DLL 来绕过 DLL 地狱,但它没有解决版本问题当时,导致程序出现故障,因为 DLL 使用了一个类 id,该 DLL 被更新的 DLL 版本替换,导致程序崩溃!

      【讨论】:

      • No *.msc 文件不是 PE 文件。令人惊讶的是,它们是 XML 文件。是的,我查过了。尝试在记事本中打开“C:\WINDOWS\system32\compmgmt.msc”、“C:\WINDOWS\system32\diskmgmt.msc”等。 :)
      • 当我们在 run 或 commandprompt 中输入 diskmgmt.msc (&回车) 我想知道命令行是如何转换成的:"C:\WINDOWS\system32\mmc.exe" "C:\WINDOWS\system32\diskmgmt.msc"
      • @Buttler:这只是标准的 Windows 魔法。这就像键入 mydocument.doc 然后打开 Word。具有 .msc 扩展名的文件通过 HKCR\.mscHKCR\mscfile 注册表项映射,以使用 mmc.exe 打开。
      • @Buttler:我同意迪沃的观点。这就是您可以调用某些程序的方式,注册表中有“扩展处理程序”,它们根据扩展名知道是 .doc、.scr、.msc 还是要打开的应用程序。真的没有什么神奇的......
      【解决方案4】:

      普通 DLL

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

      .Net DLL

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

      更多信息....Difference between Normal DLL and .Net Dll?

      马特

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-24
        • 2017-10-20
        • 2016-01-19
        • 2013-03-25
        • 2016-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多