- 组件基本概念
COM(Componet Object Model)组件是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术。在COM构架下,人们可以开发出各种各样的功能专一的组件,然后将它们按照需要组合起来,构成复杂的应用系统。由此带来的好处是多方面的:可以将系统中的组件用新的替换掉,以便随时进行系统的升级和定制;可以在多个应用系统中重复利用同一个组件;可以方便的将应用系统扩展到网络环境下;COM与语言平台无关的特性使所有的程序员均可充分发挥自己的才智与专长编写组件模块。
2.COM本质
COM本质是一种说明如何建立可动态互变组件的规范。这种规范提供了为保证能够互操作,客户和组件应遵循的二进制和网络标准。
通过这种标准将可以在任意两个组件之间进行通信而不用考虑其所处的操作环境是否相同、使用的开发语言是否一致以及是否运行于同一台计算机。
3.COM组件具备的特征
- COM组件是以Win32动态链接库(DLL)或者可执行文件(EXE)的形式发布的可执行二进制代码所组成的。
- COM组件是动态链接的。
- COM组件是完全与语言无关的。
- COM组件是可以在网络上透明的被重新分配位置的。
- COM组件是在兼容老客户的情况下悄然升级的。
- COM组件是一种给其它应用程序提供面向对象的API或服务的极好方法。
这些特征使COM组件具有很好的可重用性,这种可重用性与DLL一样都是建立在二进制基础上的代码重用。但是,COM在多个方面的表现均要比DLL的重用方式好的多。例如,在DLL中存在的函数重名问题、各编译器对C++函数名称修饰的不兼容问题、路径问题以及与可执行程序的依赖性问题等在COM中通过使用虚函数表、查找注册表等手段均被很好的解决。
其实COM组件在发布形式上本身就包扩DLL,只不过通过制订复杂的COM规范,使COM本身的机制改变了重用的方法,能够以一种新的方法来利用DLL并克服DLL本身所固有的一些缺陷,从而实现了更高层次的重用。
4.进程内组件与进程外组件
组件按照执行类型可以有两个基本形式,既可以是进程内组件也可以是进程外组件。
其中在 DLL 中实现的COM组件称为进程内组件,因为这些组件是加载到使用它们的客户端应用程序执行程序内存之中。因此当应用程序调用COM组件的服务时,就和一般的程序或函数调用一样,非常快速。
在EXE 中实现的COM组件是执行在它自己的执行程序之中,因此这种 COM组件称为进程外组件。当客户端应用程序调用在独立的执行程序中的 COM组件时必须穿越不同的执行程序,因为进程外组件在执行时会比进程外组件慢许多。
5.C#创建COM组件
5.1新建一个C#类库项目:MyCom
修改AssemblyInfo.cs文件中[assembly: ComVisible(false)],false改为true
5.2在项目中添加接口IMathManage
C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
Guid可通过 Tool -> 创建GUID产生
5.3添加一个MathManage类继承接口IMathManage
5.4项目->属性->生成下 选中"为COM互操作注册“
5.5编译
程序目标平台要保持一致
编译:生成->生成解决方案。如果没有生成.tlb文件,需要用管理员身份打开Visual Studio 2015,然后重新编译
5.6COM注册
COM 注册后才能使用。
注册过程:管理员身份运行cmd.进入
cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
注意:自己系统上安装的.net版本
输入RegAsm "E:\VSProject\COM\MyCOM\MyCOM\Out\MyCOM.dll" /tlb:MyCOM.tlb /codebase
或者Cd E:\VSProject\COM\MyCOM\MyCOM\Out
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm .exe "MyCOM.dll" /tlb:MyCOM.tlb /codebase
5.7COM卸载与注册过程基本相同,只需将命令改为
RegAsm /u "E:\VSProject\COM\MyCOM\MyCOM\Out\MyCOM.dll" /tlb:MyCOM.tlb /codebase
提示成功注册后,及可在C++上引用了
6.C++引用COM组件
6.1新建一个C++程序(控制台程序即可),本例中是CallCOM
6.2将MyCOM.tlb拷贝到CallCOM文件中。
6.3创建一个调用代码
7.VC调试C#COM的方法
7.1附加到进程
7.2驱动外部程序
8.C#调用COM组件
COM组件注册成功后,新建控制台应用程序调用COM组件
System.Type t = Type.GetTypeFromProgID("MyCOM.MathManage");//命名空间.类名
dynamic o = Activator.CreateInstance(t);
//使用com组件,不需要引用
float a = o.Add(14,5);//直接使用Add方法
Console.WriteLine("result="+a);
注:在c#的引用里,可以看得见注册的com组件
9.代码实例:https://download.csdn.net/download/liulv_yan/12655199