COM组件注册是指Windows编程中,为了使用自定义或第三方COM对象,对进程内组件(DLL)和进程外组件(EXE),利用自注册(self-registering)和非自注册组件程序而进行的操作。COM组件是微软曾经力推了很多年的一种代码复用的技术框架,在这些年里也得到了极大的发展和应用,但它的弊端却也日益明显,我们不得不面对众多的 COM组件之间的版本控制和令人恐怖的DLL地狱,还有注册表、GUID等等。在我们安装一个软件的同时,也带来了大量的我们所未知的版本繁多的COM组件到我们的操作系统中。.Net组件达到了与COM类似的目标,但是它引入了新概念,实现起来也更容易了。以下是COM组件和.NET组件的一些比较:
一、元数据
- 在COM中所有组件信息都存储在类型库中。
- .NET中信息都存储在数据集中。
- 一些COM组件有类型库,一些却没有(如VB编的,因为C++可以用IDL——接口定义语言表述接口和方法,而VB不行)。没有的话需要用C++头文件来表述接口和方法。
二、释放对象
- .NET通过垃圾回收器释放对象。
- COM组件通过引用计数管理对象,如果引用数降为零了就释放对象。
三、接口
COM有三种接口:
- 定制接口:IUnknown + 自定义接口虚方法表
- 分派接口:IDispatch
- 双重接口:IUnknown + IDispatch + 自定义接口虚方法表
四、方法绑定
- .NET前期绑定方法:虚方法表
- .NET后期绑定方法:反射
- COM前期绑定方法:设计时通过GetIdsofNames()获取方法ID,运行时只需调用Invoke()即可。
- COM后期绑定方法:运行时调用GetIdsofNames()获取方法ID,再调用Invoke()。
五、数据类型
对于分派接口和双重接口,COM使用的数据类型局限于一个自动兼容的类型列表。VARIANT是许多类型(如BYTE、INT、LONG)的组合,与.NET中Object对应。
COM数据类型 | .NET数据类型 |
---|---|
VARIANT | Object |
SAFEARRAY | Array |
BSTR | string |
IUnknown* | Object |
IDispatch* | Object |
六、注册
.NET区分私有程序集和共享程序集。每个COM组件都进行了注册配置,是全局可用的。
在使用.NET中注册组件,有三种方式:
- 手动注册: win9x/NT/2000系统提供一个用于注册进程内组件的实用工具sRegSsvr32.exe,如regsvr32 c:\test.dll;在.NET下面,注册.NET组件就需要regasm命令了,如C:\>regasm out ClassLibrary1.DLL /regfile:ClassLibrary1.reg 。
- 编程注册:使用registrationhelper类,主要是利用在iregistrationhelper接口中的方法。
- 动态注册:是指在执行应用程序过程中,检查安装组件的版本,如组件的正确版本没安装,则在运行时自动安装需要的版本,即自动注册。
.NET组件技术的目标之一就是改善COM的缺陷,同时维持COM的核心概念,使得组件开发更加简单。
七、组件
(1).NET组件具有自描述能力,不依赖于注册表。.NET组件与元数据一起编译,元数据作为编译组件(在.NET中称为Assembly)的一部分进行保存,元数据能够对组件进行详细描述,包括组件的接口、所支持的类型及开发人员添加的自定义信息。由于.NET组件无须在windows注册表中注册,大大简化了.NET应用程序的部署与安装。
(2).NET组件不再有“DLL Hell”问题。同一组件的多个版本可以同时共存。由于.NET组件不像COM组件那样依赖于注册表中的GUID,因此同一组件的多个版本不会产生冲突,.NET应用程序可以通过编辑应用程序配置文件来指定使用哪个版本的DLL。