技术开发 频道

从感知客户端使用.NET 组件:创建一个.NET组件


进一步理解COM Interop wizardry

    让我们看一下当注册程序集时,Regasm.exe创造的注册途径。



    通过打开被REGASM生成的类型库,你可以检查OLEVIEW.EXE里的组件CLSID 。检查coclass 章节下面的uuid 属性。如果浏览到注册中的HKCR\CLSID\{...Component's CLSID...}键,可以看到REGASM 早已创建了一个被COM要求的相关联的注册途径,以此来激活包含在Inproc 服务器中的对象。除此以外,它还创建了其它一些注册途径,例如:类型, 程序集, 以及运行库译本,.NET执行时要用到这些途径。mscoree.dll 上设置了Inproc 服务器处理程序(由InProc服务器32键默认值显示),Inproc 服务器处理程序是通用语言执行层执行时执行驱动的核心。COM运行库调用MSCOREE.dll (通用语言执行层运行库)里的DllGetClass对象入口点。 然后运行库使用Class ID (CLSID),把它传递到DllGetClass对象,检查InProc服务器32 键下面的程序集和类型,以此来下载并且解决.NET程序集,此.NET程序集将为这个要求服务。运行库也动态地创建一个COM可调用包装程序(COM可调用的包装),处理非托管代码和托管组件之间的交流。这使得COM 感知客户端认为它们正在与Classic COM组件交流,使得.NET 组件认为它们正在接受来自于托管应用程序的要求。这里有一个被每一个.NET组件实例创建的COM可调用的包装。



    正如谚语所说,一幅图胜过千言万语,因此当COM 感知客户端与一个.NET 组件交流时,理解简单外表下面发生了什么。这里主要的参与者就是通用语言执行层运行库和COM可调用包装程序(COM可调用的包装),通用语言执行层运行库和COM可调用包装程序(COM可调用的包装)是由.NET 运行时假冒创作的。从那以后,COM可调用的包装 管理并且处理大部分的基础工作,让两者一起工作。在这里,COM可调用的包装 处理生命周期管理问题。非托管领域里的COM 客户端将引用计数保持在COM可调用的包装 代理上而不是在实际的.NET 组件上面。COM可调用的包装仅仅拥有.NET组件的引用。 .NET组件和其它任何托管类型一样,以通用语言执行层 垃圾回收站的准则为生。COM可调用的包装属于非托管 heap,当COM 感知客户端不拥有任何对象的引用时,COM可调用的包装就崩溃了。就像运行库可调用的包装一样,COM可调用的包装也有调用参数,这些调用参数在非托管客户端和托管 .NET组件之间来回移动。它负责按要求合成虚拟函数表。特殊接口的虚拟函数表是被动态地生成的。只有当COM 感知客户端通过QueryInterface调用,真正请求一个特殊接口时,就会懒散地创建特殊接口的虚拟函数表。COM可调用的包装代理上的调用最后被发送到一个存根,此存根真正地把调用制成托管对象。
0
相关文章