当前位置: 首页 > 编程语言 > C#

如何通过CLR加载DLL?分享

时间:2023-04-10 10:52:30 C#

如何通过CLR加载DLL?我的假设一直是CLR加载应用程序域在启动时需要的所有DLL。然而,我写了一个例子让我质疑这个假设。我启动我的应用程序并检查加载了多少模块。Process[]ObjModulesList;ProcessModuleCollectionObjModulesOrig;//获取进程内的所有模块ObjModulesList=Process.GetProcessesByName("MyProcessName");//填充模块集合。ObjModulesOrig=ObjModulesList[0].Modules;Console.WriteLine(Origb.Modules.ToString());然后我重复完全相同的代码,但我的计数不同。附加的DLL是C:\WINNT\system32\version.dll。我真的很困惑为什么计数不同。有人可以详细说明CLR在做什么以及它如何加载这些东西,以及它在做什么逻辑吗?以下内容摘自DonBox的优秀Essential.Net。(此处)(恕我直言,任何专业.Net开发人员都必须拥有)CLR加载器CLR加载器负责加载和初始化程序集、模块、资源和类型。CLR加载程序加载和初始化尽可能少。与Win32加载程序不同,CLR加载程序不解析并自动加载依赖模块(或程序集)。取而代之的是,依赖部分仅在实际需要时按需加载(与VisualC++6.0的延迟加载功能一样)。这不仅加快了程序初始化时间,而且减少了运行程序所消耗的资源量。在CLR中,加载通常由基于类型的即时(JIT)编译器触发。当JIT编译器试图将方法体从CIL翻译成机器代码时,它需要访问声明类型的类型定义以及类型字段的类型定义。此外,JIT编译器需要访问JIT编译方法的任何局部变量或参数使用的类型定义。加载类型意味着加载包含类型定义的程序集和模块。这种按需加载类型(以及程序集和模块)的策略意味着程序中未使用的部分永远不会进入内存。这也意味着运行的应用程序经常会看到随着时间的推移加载新的程序集和模块,因为在执行期间需要这些文件中包含的类型。如果这不是您想要的行为,您有两种选择。一种是简单地声明一个类型的隐藏静态字段来与加载程序交互。加载器通常代表您隐式执行它们的工作。开发人员可以通过程序集加载器显式地与加载器交互。程序集加载程序通过System.Reflection.Assembly类上的LoadFrom静态方法向开发人员公开。此方法接受CODEBASE字符串,它可以是文件系统路径或标识包含程序集清单的模块的统一资源定位器(URL)。如果找不到指定的文件,加载程序将抛出System.FileNotFoundException异常。如果可以找到指定的文件但不是包含程序集清单的CLR模块,则加载程序将引发System.BadImageFormatException异常。最后,如果CODEBASE是使用file:以外的方案的URL,则调用者必须具有WebPermission访问权限,否则将抛出System.SecurityException。此外,在URL上使用file:以外的协议的程序集在加载之前首先下载到下载缓存。清单2.2显示了一个简单的C#程序,它加载位于file://C:/usr/bin/xyzzy.dll的文件,然后创建一个名为AcmeCorp.LOB.Customer的包含类型的实例。在此示例中,调用者提供的只是程序集的物理位置。当程序以这种方式使用程序集加载程序时,CLR会忽略程序集的四部分名称,包括其版本号。示例2.2.使用System;加载具有显式代码库的程序集;使用System.Reflection;publicclassUtilities{publicstaticObjectLoadCustomerType(){Assemblya=Assembly.LoadFrom("file://C:/usr/bin/xyzzy.dll");返回a.CreateInstance("AcmeCorp.LOB.Customer");虽然按位置加载程序集有点有趣,但大多数程序集都是使用程序集解析器按名称加载的。程序集解析器使用由四部分组成的程序集名称来确定要使用程序集加载程序将哪个基础文件加载到内存中。如图2.9所示,这个名称到位置的解析过程考虑了多种因素,包括托管应用程序的目录、版本控制策略和其他配置细节(所有这些都将在本章后面讨论)。程序集解析器通过System.Reflection.Assembly类的Load方法公开给开发人员。如清单2.3所示,此方法接受由四部分组成的程序集名称(作为字符串或AssemblyName引用),表面上类似于程序集加载器公开的LoadFrom方法。相似之处只是肤浅的,因为Load方法首先使用程序集解析器通过一系列相当复杂的操作来查找合适的文件。第一个操作是应用版本策略来确定应加载的所需程序集的确切版本。示例2.3。使用程序集解析器使用System加载程序集;使用System.Reflection;publicclassUtilities{publicstaticObjectLoadCustomerType(){Assemblya=Assembly.Load("xyzzy,Version=1.2.3.4,"+"Culture=neutral,PublicKeyToken=9a33f27632997fcc");返回a.CreateInstance("AcmeCorp.LOB.Customer");}}CLR按需加载程序集。当你执行一个方法时,它会查看它的位置(哪个模块等),如果没有加载它,它就会加载它。这是一篇关于CLR性能的文章,并讨论了加载程序集:当CLR即时(JIT)编译Start方法时,它需要加载该方法中引用的所有程序集。这意味着将加载异常处理程序中引用的所有程序集,即使应用程序的大部分执行可能不需要它们。这篇文章是针对SilverLight的,但它确实讨论了CLR会发生什么。这与您的问题有点不同,但是如果您不希望按需加载所有程序集,您可以一次加载所有程序集。像这样的东西应该可以解决这个问题//我发现获取类型在确保加载类型方面做得很好。asm.GetTypes();每当创建相应的COM对象时,COMDLLS就会按需加载。这也可能发生在非COMdll上。以上就是C#学习教程:如何通过CLR加载DLL?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: