C#与DLL和COM的混合编程(3)- 高级COM互操作(Advanced COM Interop)

  Advanced COM Interop


.NET framework 是从COM的一种自然地进步,因为这两个模型共享了许多中心的主题,包括组件重用和语言中立。为了支持向后兼容,COM interop提供了不需要修改现有组件而能访问现有COM组件的方法。可以通过使用COM interop工具导入相关的COM类型来合并COM组件到.NET Framework的应用中。一旦导入,COM的类型就可以使用了。

COM interop 同时也提供了向前兼容使得COM的客户可以像访问其他的COM对象一样访问托管的代码,COM interop又一次的提供了所谓的无缝从程序集中导出元数据(metadata)到类型库并且像传统COM组件一样注册托管组件的方法。无论是导出还是导入工具处理的结果都与COM规范一致。在运行时,如果需要的话common language runtime在COM对象和托管代码之间列集(marshals)数据


1. COM Wrappers
COM在以下几个方面与.NET Framework的对象模型有所不同:
• COM对象的客户程序必须管理这些对象的生命期;在.NET Framework 中CLR管理这些对象的生命期
• COM的客户通过请求一个接口并得到接口的指针来查询一个服务是否有效,.NET的客户可以通过反射(reflection)来得到一个对象的功能的描述
• .NET的对象驻留在.NET Framework执行环境管理的内存中,执行环境可以因为性能的原因删除内存中的对象并且更新它删除的对象的所有引用。非托管的客户,得到一个对象的指针,依赖于对象保留在相同的位置。这种客户没有那种处理在内存中不在固定位置的对象的机制。


为了克服这些不同,runtime提供了包装类使得托管代码和非托管代码的客户都认为他们在自己的环境中调用对象的方法。当托管客户调用一个COM对象的方法时,runtime创建一个runtime callable wrapper (RCW)。RCWs抽象了托管代码和非托管代码引用机制的不同。Runtime还创建了一个COM callable wrapper (CCW)来实现其逆过程,使得COM的客户能够无缝的调用.NET对象的方法。如下图所示


COM wrapper overview



在大多数情况下,标准的RCW或者CCW由runtime生成,为跨越COM和.NET Framework的边界调用提供了足够的列集。使用自定义的属性,可以随意的调整runtime表示托管代码和非托管代码的方式

Runtime Callable Wrapper


CLR(common language runtime)通过一个叫做runtime callable wrapper (RCW)的代理(proxy)暴露COM 对象. 虽然RCW对于.NET的客户似乎是一个普通的.NET对象,但是它的主要功能却是在.NET客户和COM对象之间列集调用。


运行时正确的为每个COM对象创建一个RCW,而不管那个对象上存在的引用的个数。如下图所示:任意数量的托管客户可以保持一个暴露INew 和INewer 接口的COM对象的引用。运行时为每个COM对象维护一个单独的RCW。


Accessing COM objects through the runtime callable wrapper



使用来源于类型库(type library)的元数据(metadata),运行库(runtime)创建将被调用COM对象和这个对象的包装(wrapper)。每个RCW维护它所包装的COM对象的接口指针并且在RCW不再需要时释放COM对象。运行库(runtime)在RCW之上作垃圾收集。


在其他的活动中,RCW代表所包装的对象在托管和非托管代码之间列集(marshals)数据。特别的是,RCW在客户和服务有不同的数据表现形式,并需要在他们之间传递数据时,提供方法参数和方法返回值得列集。


标准的wrapper执行内置(built-in)的列集规则。例如:当.NET的客户传递一个String类型作为参数的一部分给托管对象的时候,wrapper把string类型那个转化为BSTR类型。当COM对象返回一个BSTR给托管的调用着的时候,调用着收到一个string。无论是客户还是服务端接受和发送数据都使用自己熟悉的类型。还有一些其他的类型不需要变化,例如:一个标准的wrapper将在托管和非托管代码之间一直传递4-byte integer而不做任何变化。


RCW的主要目标就是隐藏托管代码模型和非托管代码模型之间的差别,实现无缝的传输。RCW使用选择的接口而不把它们暴露给.NET的客户端,如下图所示


COM interfaces and the runtime callable wrapper



当创建一个早期的COM对象的时候,RCW是一个特殊的类型。它实现了COM对象实现的一些接口并且暴露它们的方法,属性和时间。如图所示:RCW暴露了INew接口,但是使用了IUnknown 和IDispatch接口。RCW向.NET客户暴露了INew的所有成员


COM Callable Wrapper


当COM的客户调用.NET的对象时,CLR创建这个托管的对象和这个托管的对象COM callable wrapper(CCW),COM客户可以使用CCW作为托管对象的一个代理,而不能够直接使用.NET的对象。

 
Runtime正确的创建托管对象的CCW,不管要求这个服务的COM客户的数量。如下图所示,多个COM客户可以保持包含INew 接口的CCW的引用,CCW,反过来包含一个实现了接口和垃圾收集的托管对象的单独的引用。COM和.NET的客户可以同时在相同的托管对象是发起调用。


Accessing .NET objects through COM callable wrapper


COM callable wrappers对于运行在.NET Framework上的其他类是不可见的。它们的主要目的是在托管和非托管代码之间列集(marshal)调用,而且CCWs同时也管理着它所包含对象的identity和对象的生存期(lifetime)


Object Identity
运行时(runtime)在它的能够垃圾回收的堆里(garbage-collected heap)为.NET对象分配内存,这能使runtime需要的时候在内存中移动对象。相反,runtime在不能进行垃圾收集的堆上为CCW分配内存,使COM客户能够直接引用它。


Object Lifetime
与它所包含的.NET 对象不同,CCW是一个基于引用计数的传统的COM。当CCW的引用计数减少到0,wrapper释放自己在托管对象上的引用。没有引用的托管的对象在下一次垃圾收集的周期内将被收集。


Customizing Standard Wrappers
这部分将描述如何自定义标准的runtime callable wrappers(RCW) and COM callable wrappers.(CCW)


Runtime Callable Wrappers
当.NET激活一个COM对象时,运行时(runtime)生成一个包含COM类型的runtime callable wrapper (RCW),如下图所示, 运行时(runtime)使用从导入的类型库而得到的元数据(metadata)来生成RCW。Wrapper根据interop marshaling service定义的规则列集数据。


RCW generation and method calls




有两个方式可以自定义RCW。如果你可以修改Interface Definition Language (IDL)的源文件,你可以给type library file (TLB) 添加属性然后导入TLB。还可以应用interop-specific attributes来导入类型生成新的程序集(assembly)支持自定义的标准RCWs被这些attributes限制


To modify the IDL source

1. Apply TLB attributes to libraries, types, members, and parameters. Use the custom keyword and an attribute value to change metadata. By applying TLB attributes, you can:
• Specify the managed name of an imported COM type, instead of allowing the import utility to select the name according to standard conversion rules.
• Explicitly define a destination namespace for the types in a COM library

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值