COM Interop 理论与实践

本文详细介绍了.NET框架下的COMinterop理论与实践,包括COM组件的导入与使用、COM封装、HRESULTs与异常处理、继承、聚合等内容。文章还探讨了如何生成及处理COM组件的事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

COM interop理论/实践
  在.NET框架下,开发人员可以通过COM interop tools COM组件导入导一个应用中去,一旦导入成功,那么我么就可以非常容易地调用COM接口给我们所提供的方法了。

  A .NET Framework developer can incorporate COM components into a managed application by using COM interop tools to import the relevant COM types. Once imported, the COM types are ready to use.

一、COM interop 概述:

COM Interop看上去象是介乎于COM.Net之间的一条纽带,一座桥梁。为了保持向后兼容,COM Interop可以使得.Net程序在不修改原有COM组件的前提下方便的访问COM组件。这一点是非常重要的。事实上,全球的COM组件的代码量估计可能有数十亿行,拥有这些COM组件的公司不可能重写这些组件,所以COM Interop的存在为有此需求的开发者提供了很好的解决方案。

COM.NET之间存在着非常大的差异,为了使两者可以有机的结合在一起进行协同工作,COM Interop中实际存在着2种桥接方式。一种是RCWRuntime Callable Wrapper;另一种是CCWCOM Callable WrapperRCW是在运行时通过CLRInterop装配件(Interop Assembly)的元数据中获取相关信息动态的实例化而得到的。使用者将感觉不到自己是在调用COM组件,一切都是这么的自然,和调用一个.Net组件没有任何区别。  

需要注意的是,一个COM组件(指的是一个实例,即一个DLL文件)由且仅由一个RCW负责维护。那么这儿有一个问题了,对于一个COM组件的不同版本,是不是就会有不同的RCW与之相对应呢?答案是肯定的。那有些朋友会说,.Net中的组件不是已经解决了COM中的“DLL HELL”问题了吗?按上面的说法,似乎并没有得到解决嘛?这儿我要说的是,在.Net中导入一个COM组件的不同版本,是会出现此类问题。解决此类问题的方法是使用PIA(Primary Interop Assembly)

.Net提供三种方法来导入一个COM组件

l         通过Visual Studio .Net提从的“添加引用”功能

l         通过tlbimp.exe实现

l         使用System.Runtime.InteropServices.TypeLibConverter编程

下面就分别介绍COM的封装、HRESULTs and Exceptions、继承、聚合和包容、如何运用COM interop来生成发出事件和处理事件以及System.Runtime.InteropServices命名空间几个重要的概念

1.        COM的封装(COM Wrappers)

l         在一般的语言(诸如C++)当中在客户端我们一定要控制该COM对象的生命周期

l         客户端的COM对象的方法在C++中的调用通过产生该对象的实例同时获得该对象的接口指针,通过接口指针来访问该对象的方法。在.NET框架下则可以直接通过函数的映射来获得(Clients of .NET objects can obtain a description of an object's functionality using Reflection.)

l         .NET框架下的运行环境中.NET可以在内存中为.NET重新对象分配内存使用。(NET objects reside in memory managed by the .NET Framework execution environment.)

为了解决上述问题,.NET提供一个COM Wrappers.它可以使得Managed Code Unmanaged Code可以很好结合在一起。COM Wrappers两种桥接方式RCW(runtime callable wrapper)CCW(COM callable wrapper)其中RCW是将Managed的客户端与Unmanaged服务器端联接起来的;CCW是将Unmanaged的客户端与 Managed服务器端联接起来的。

2.        HRESULTs and Exceptions

COM编程中我们通过HRESULT来判断所做的操作是否成功,在.NET框架下我们通过抛不同的异常(Throw Exceptions)来捕捉错误。

MSDN给我们列出了HRESULT不同值与.NET的不同异常的对照表。(.NET Framework Developer’s Guide—HRESULTs and Exceptions)

3.        继承、聚合和包容(Inheritance,Aggregation and Containment)

继承:.NET提供一些标准的接口,用户在定义接口时,可以继承这些接口。

聚合:.NET也支持COM提供的聚合的概念即,外对象将内对象的接口暴露在用户面前。

包容:

    通过在外对象的构造函数中创建内对象的实例,这样客户端就可以通过该实例获得接口进行调用接口的各个方法。

4.        如何运用COM interop来生成发出事件和处理事件

在以下内容中,将要描述有关COM对象出接口与事件接收器的连接机制。

关于COM对象的出接口与事件接收器之间的连接机制与在描述COM原理与应用中的机制是一样的,即COM对象声明一个出接口,在事件接收器中表示该接口的实现方法。一旦,COM对象与事件接收器的连接建立好以后,那么客户端就可以随时接收到COM对象服务器端的事件、消息。下面我们从C#服务器端和事件接收器两个方面来描述这个问题。

Handling Events Raised by a COM Source(描述COM源对象是如何产生一个事件的)

Raising Events Handled by a COM Sink(通过接收器来处理事件)

5.        System.Runtime.InteropServices命名空间

System.Runtime.InteropServices是一个有关访问COM对象以及在.NET框架下的本地API函数。在创建COM接口时经常要运用这个命名空间。

二、C#接口编程

     下面将从接口的定义、接口的访问、接口的实现以及接口的转换编程这些方面来阐述运用C#进行接口编程的方法。

1. 接口的定义

接口的声明:

[attributes] [modifiers] interface identifier [:base-list] {interface-body}[;]

l         attributes(可选):附加的定义性信息

l         · modifiers(可选):允许使用的修饰符有new和四个访问修饰符。分别是:newpublicprotectedinternalprivate。在一个接口定义中同一修饰符不允许出现多次,new修饰符只能出现在嵌套接口中,表示覆盖了继承而来的同名成员。The public, protected, internal, and private修饰符定义了对接口的访问权限。

l         指示器和事件。

l         identifier:接口名称。

l         base-list(可选):包含一个或多个显式基接口的列表,接口间由逗号分隔。

l         interface-body:对接口成员的定义。

l         接口可以是命名空间或类的成员,并且可以包含下列成员的签名: 方法、属性、索引器

l         一个接口可从一个或多个基接口继承。

接口的主体:

               interface-body:  {   interface-member-declarationsopt   }

接口可以包含一个和多个成员,这些成员可以是方法、属性、索引指示器和事件,但不能是常量、域、操作符、构造函数或析构函数,而且不能包含任何静态成员。接口定义创建新的定义空间,并且接口定义直接包含的接口成员定义将新成员引入该定义空间。

   2. 接口的访问

       C#中的CASTS来代替QueryInterface

       (Using Casts Instead of QueryInterface)

C++中客户端需要通过QueryInterface来获得COM对象的接口指针。在C#编程中却不必这么麻烦。我们可以直接将COM对象对应到相应的COM接口上。如果我们在程序中对应错误,那么在运行时C#会抛出异常。

   3. 接口的实现

              显示地实现接口成员即可以直接利用类来实现接口的成员函数如:

         // Since the .NET Framework interface and coclass have to behave as

         // COM objects, we have to give them guids.



From: http://www.99inf.net/SoftwareDev/VC/38278.htm
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值