欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表
最新评论

作为COM组件的CLR

创建时间:2013年07月08日 21:29  阅读次数:(5129)
分享到:
你还可以通过COM+l.x目录管理器(COM+l.x catalog manager)注册一个基于CLR的类型。基于CLR的类型如果要以COM+进行配置,则必须直接或者间接地继承System.EnterpriseServices.SarvicedComponent基类型。这个基类型确保基于CLR对象具有COM+l.x 上下文与之关联。对于CLR第1版,COM+l.x服务仍然是通过非托管的COM代码实现的ServicedComponent的使用相当于CLR的标志,用于确保CLR和COM+l.x上下文对新对象都有效,当 CLR创建服务组件的实例时,它要确保对于这个类有适合的COM+l.x目录项。为此,绝大多数COM+l.x目录特性作为元数据特性是有效的,它们允许开发人员在开发时(development time),指定他们的COM+1.x服务需求。

最后,为了避免使用COMinterop,CLR通过System.Enterprise Services.Context.Util类型,使CoGetObjectContext工具有效。截止到本书写作时,COM+l.x为了保证这种管道(plumbing)的使用,其独有的特征使运用分布式事务协作(distributed transaction coordinator,DTC)更为简便。当然,不需要DTC的应用程序可能也不会需要COM+1.x。要获得更多的内容,可以参见Tim Ewald的专著《Transactional COM+》(Addison-Wesley,  2001)。

作为COM组件的CLR


前面描述的有关MSCOREE.DLL的所有使用都隐式地利用了CLR,而由非托管程序显式地使用CLR也是可能的。当你显式地使用CLR时,非托管程序具有相当多的控制能力,远远超出了进程中配置CLR的情形。为了易于实现,CLR公开了一组基于COM的宿主接口,这组接口能够从任何COM兼容的环境中被访问。在这些接口中,最为关键的就是ICorRuntimeHost。

ICorRuntimeHost是CLR主要的宿主接口。它允许程序管理CLR的AppDomain,以及控制os线程和纤程(fiber)与CLR的交互,获取ICorRuntimeHost的最简单方式就是在CorRuntuneHOSt协作类上调用CoCreatelnstance。考察下面的VBA6.0代码:
Private Sub Form_Load()
Dim rt As mscoree.CorRuntimeHost
Dim unk As stdole.IUnknown
Dim as As mscorlib.AppDomain
Dim s As mscorlib.Stack
Set rt=New mscoree.CorRuntimeHost
rt.Start
rt.GetDefaultDomain unk
Set ad=unk
Set s=ad.CreateInstance(“mscorlib”_”System.Collections.Stack”).Unwrap
s.Push “Hello”
s.Push “Goodbye”
s.Push 42
MsgBox s.Pop()
MsgBox s.Pop()
MsgBox s.Pop()
End Sub

假定这些代码在引用MSCOREE.TLB和MSCORLIE.TLR的工程中,new语句将导致MSCOREE.DLL加载到进程中。注意,在使用CLR之前,有一个显式的Start方法必须调用。这种初始化分为两个阶段,它允许容器使用AppDomainSetup对象来配置默认的AppDomain加载器的属性。在Start方法被调用后,进程的默认域将被初始化,并且通过GetDefaultDomain
方法使其有效。在默认域有效之后,宿主程序中可编程的CLR就非常类似于从CLR内部对CLR编程。两者的主要差别在于宿主程序是非托管代码,因此,由GetDefaultDomain返回的引用是针对底层基于CLR对象的ccw。

使用CoCreateInStance加载CLR有两个缺陷。一个是:你不能显式地控制要加载的CLR版本,准确地说,CLR将使用前面描述的Version属性。并且,使用CoCreatelnstance需要你在进程中初始化COM。实际中的某些的进程不使用OLE32.DLL。为了让CLR能寄宿在这些进程中,MSCOREE.DLL公开了一组API函数,用于加载当前运行时,而不用求助于COM。这些API调用中最为灵活的就是CorBindToRuntimeHost。

CorBindToRuntimeHost允许调用方指定几个参数,用于控制哪种CLR构建体被加载,以及它将如何被初始化。下面是CorBindToRuntimeHost函数的签名:


第1个参数覆盖出现在注册表或者是环境变量中的Version属性。第2个参数标明所期望的是单处理程序还是多处理程序构建体。然而,当运行在单处理程序机器上时,MSCOREE.DLL将忽略用于svr的请求。第3个参数是应用程序配置文件的文件名。它允许宿主程序使用任何名字配置文件。第5个参数是由下面枚举而来的位掩码(bitmask):


加载器优化标记对应第8章描述的System.LoaderOptimization枚举。STARTUP_LOADER_SAFEMODE标记与safemode配置文件特性具与相同的功能,消除采用MSCOREE.DLL的默认版本策略。最后,STARTUP_CONCURRENT_GC标记通知CLR,要求按qcConcurrent配置文件元素的方式使用同步垃圾回收器。CorBindToRuntimeHost的最后三个参数匹配那些在CoCreateInstance调用中用到的参数,并且标明将用到哪些协作类和接口。

配置文件的存在将影响CorBindToRuntimeHost的参数,尤其是配置文件将优先于传递给CorBindToRuntimeHost的参数。这将影响到用于加载CLR的整个版本策略(如图10.8所示)。
在运行时决定CLR版本
在运行时决定CLR版本

MSCOREE.DLL在CorBindToRuntimeHost上能导出几个变体,它们可以接收更少的参数。然而,由MSCOREE.DLL导出的两个函数需要仔细研究,CorBindToCurrentRuntime和ClrCreateManagedInstance。前一个函数允许非托管代码访问ICorRuntimeHost引用,它引用的是已经在进程内初始化的运行时,后一个函数接收一个完全限定的CLR类型名,并且封装了对CorBindToRuntimeHost、ICorRuntimeHest.GetDefaultDomain和AppDomain.CreateInstance的底层调用。

由CorBIndToRuntimeHost返回的对象能够提供额外的功能,但这已经超出了我们讨论的范畴。尤其是在如何管理垃圾回收器和线程方面,它为宿主程序提供了更为细化的控制。图10.9为整个对象模型。这些接口都没有文档化;你可以通过实验很容易地推断出来, ICorThreadpool接口允许非托管代码访问CLR进程范围的线程池。方法ICorThreadpool镜像那些它托管的线程副本:System.Threading. Threadpool.IGCHost接口允许设置各种阀值(threshold),用于垃圾回收器的堆管理器,以及检查堆使用信息。IValidator接口公开PE/COFF的CLR验证功能,允许任何工具 (例如,peverify.exe)验证基于CLR的模块。IMetaDataConverter接口公开了TLB到CLR元数据的转换工具,并已经有诸如TLBEXP.EXE的应用工具。

CLR也允许宿主应用程序注册几个回调接口,以获得对垃圾回收器与线程管理器工作的更好控制。当垃圾回收器在给定线程被挂起或者重新开始执行时.IGCHostControl接口允许CLR通知宿主应用程序。IGCHostControl接口允许宿主应用程序控制垃圾回收器为其堆内存分配虚拟内存的速度和程度。最后,当 CLR调试器可能挂起给定线程时,IDebuggerThreadControl接口允许CLR通知宿主。
 CLR宿主对象模型[>f:yl
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 73+69=? 的结果(结果是:142)
结  果: