应用COM和接口可用 .pdf
《应用COM和接口可用 .pdf》由会员分享,可在线阅读,更多相关《应用COM和接口可用 .pdf(45页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第六讲应用 COM 和接口前面我们已经说明,.NET 战略的一个重要方面,就是弱化COM 的应用,这似乎是说,我们不再需要研究COM 了,但事实并非如此,其中一个重要的原因,是COM 已经流行了十年,而且, COM 也是微软和其它众多软件开发的基础,更不用说,.NET 平台本身还使用了COM+ 技术。基于这一系列的原因,我们不得不来研究在.NET 中应用COM 和接口的有关问题。在这一讲里,我们将首先对COM 做一个简要的回顾,其实COM 的问题并不太复杂,但是令人费解的是,很多软件方面的著作,都把COM 作为一个重要的主题来研究,其实这是没有太多的必要的。我们研究这一讲的内容的时候,首先要记
2、住的是,在很大程度上.NET 是从 COM 演变来的,按照进化的观点,COM 类似于 Lucy(古埃塞俄比亚的南猿),所以如果它显得比较笨的话,你不要太介意,因为没有笨拙的COM ,就没有流畅的.NET 。一、COM 简介COM (Component Object Model )也就是组件对象模型,是微软为编程创建语言独立性所做的第一次好的尝试。COM 是一种用于说明如何建立软件组件的规范,由于使用了统一的接口规范,不同的开发人员创建的COM 组件,可被组合进不同的应用程序中,而且这些COM 组件所使用的语言,可以是完全不同的。例如,你可以在VC+程序中调用VB 组件,反之亦然。这对于一个开发
3、软件的集体来说,是有很大的意义的。DCOM (Distributed Component Object Model)分布式组件对象模型,这是一种分布式应用程序集成到网络的技术,一个分布式应用程序由多个进程组成,这些进程协作完成一项工作。DCOM 为 COM 组件之间的通信透明的提供可靠、安全和有效的支持,这些组件包括ActiveX ,脚本和Java小程序。DCOM可将其应用程序分布到最适合于其顾客和应用程序的位置。在很大程度上,DCOM是带宽、部署和防火墙问题的综合,所以也就决定了它不会为太多的人所认可。际上并不知道自己在开发COM 对象。讨论这个问题的意义在于,假定一个企业的系统,已经长期的
4、很好的使用一个COM 对象,现在,企业系统要用.NET 升级,这就面另两个选择:第一种,一切重新开始,用新的平台特性,开发新的内容,当然这是很好的,但有时候并不一定合算。第二种,一些经过考验被认为合理的组件,还可以在.NET 平台上使用,这将会大大减少开发时间和难度,我们下面要讨论的就是这种方法。我们首先在VC+ 中开发一个COM 组件,然后讨论在.NET 上的应用问题。二、在 C+中开发 COM 组件VC+ 一直是专业开发人员最青睐的语言之一,现在的 VC+.NET , 不但保留了原来的VC+ 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - -
5、- - - - 名师精心整理 - - - - - - - 第 1 页,共 45 页 - - - - - - - - - 6.0 的能力,而且还提供的平台托管代码的编写能力,可谓如虎添翼。这里主要利用VC+ 开发标准的COM 组件,然后用C#调用。开发 COM 组件,首先必须生成四个标准函数:DllRegisterServer :实现在注册表中注册COM 服务的功能。DllUnregisterServer :和上面的功能刚好相反,实现在注册表中注销的功能。DllCanUnloadNow :用来检测是否可以从内存中卸载COM 服务器。如果COM 客户第一个调用COM 服务,系统会自动把COM 服务
6、载入内存,但又有客户访问COM 服务的时候,只是增加COM 服务被调用的计数,当计数为0 时,则自动卸载。DllGetClassObject :返回 COM 类对象的指针。COM 技术的原理是比较复杂的,好在VC+ 提供了活动模板库(ATL) ,可以帮组我们完成标准的框架部分,我们只要关心我们必需处理的属性和方法就可以了。下面讨论一个最简单的例子,但是这个例子表达了VC+ 生产 COM 组件最重要的要素,通过这个例子,更复杂的东西也能够做出来。首先生成一个ATL 项目。名字为: myCom 因为要处理字符串(CString) ,所以选择支持MFC 。这里不需要属性化。添加一个类。选择: ALT
7、 简单对象。给对象恰当的名字。注意,对象可以有多个。名字为: MyShow 添加一个属性:Name,返回值为BSTR。这是可以在COM 对象之间传递的字符串格式。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 45 页 - - - - - - - - - 添加方法: HelloiWorld 。主要目的是把Name 属性的字符串处理以后输出。参数为: BSTR* ,这表达一个输出的字符串指针。加入一个求和方法:Sum 注意:返回类型必须是HRESULT ,真正的返回值是在参
8、数属性中选择“类型*” (指针),然后,选择retval。不选则为void。in,表达为传入值,一般用值类型。out 为参数表的传出值(out) ,调用的时候必须out,retval 为返回值。乘法: Multiply 同样的方法,加入乘法的方法:Multiply 处理代码,文档:MyShow.cpp /保留属性的值。/因为要处理汉字,这里使用CStringW /此外还有CString、 CStringA CStringW strName; STDMETHODIMP CMyShow:get_Name(BSTR* pVal) AFX_MANAGE_STATE(AfxGetStaticModule
9、State(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 45 页 - - - - - - - - - / TODO: 在此添加实现代码/返回值,注意CString 向 BSTR 的转换*pVal=strName.AllocSysString(); return S_OK; STDMETHODIMP CMyShow:put_Name(BSTR newVal) AFX_MANAGE_STATE(AfxGetStaticModuleState(); /传入值strNa
10、me=newVal; / TODO: 在此添加实现代码return S_OK; STDMETHODIMP CMyShow:HelloWorld(BSTR* s) AFX_MANAGE_STATE(AfxGetStaticModuleState(); / TODO: 在此添加实现代码/注意,字符串是如何拼接的CStringW message(你好,你的名字是:); message+=strName; *s=message.AllocSysString(); return S_OK; STDMETHODIMP CMyShow:Sum(DOUBLE x, DOUBLE y, DOUBLE* s) A
11、FX_MANAGE_STATE(AfxGetStaticModuleState(); / TODO: 在此添加实现代码/注意,如何把处理的结果返回名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 45 页 - - - - - - - - - *s=x+y; return S_OK; STDMETHODIMP CMyShow:Multiply(DOUBLE x, DOUBLE y, DOUBLE* s) AFX_MANAGE_STATE(AfxGetStaticModuleS
12、tate(); / TODO: 在此添加实现代码/同样要把处理的结果返回*s=x*y; return S_OK; 生成的时候同时注册。必要的时候,可以人工注册和卸载:Regsvr32/s .DLL - 注册Regsvr32/u .DLL - 注销在.NET 中应用。myComLib.IMyShow obj=new myComLib.MyShowClass(); /加法private void button1_Click(object sender, System.EventArgs e) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - -
13、- - 名师精心整理 - - - - - - - 第 5 页,共 45 页 - - - - - - - - - textBox3.Text=obj.Sum(double.Parse(textBox1.Text),double.Parse(textBox2.Text).ToString(); /减法private void button2_Click(object sender, System.EventArgs e) textBox3.Text=obj.Multiply(double.Parse(textBox1.Text),double.Parse(textBox2.Text).ToStri
14、ng(); /写属性private void button3_Click(object sender, System.EventArgs e) obj.Name=textBox1.Text; /读属性private void button4_Click(object sender, System.EventArgs e) textBox3.Text=obj.Name; /调 HelloWorld private void button5_Click(object sender, System.EventArgs e) textBox3.Text=obj.HelloWorld(); 结果应该是没
15、有问题的。三、在 Delphi 中开发 COM 组件很多语言都有生成COM 组件的能力,下面做一个Delphi 的例子。1新建 ActiveX 库名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 45 页 - - - - - - - - - file - new - other - ActiveX - ActiveX Libray OK 产生一个项目文件DllGetClassObject, DllCanUnloadNow, DllRegisterServer, DllUnr
16、egisterServer; 2创建 COM 对象File - new -Other -ActiveX -COM object OK 类对话框:输入类名:比如MyShow 出现一个统一的类生成器:IMyShow - 接口MyShow -实现这个接口的对象在 IMyShow 右键-New - Property 添加一个属性,Name 名字起为: Name 再添加一个方法:Method Name 名字起为: HelloName 关于属性,一般的形式是:protected function Get_name: WideString; stdcall; procedure Set_name(const
17、 Value: WideString); stdcall; end; . function TMyShows.Get_name: WideString; begin end; procedure TMyShows.Set_name(const Value: WideString); begin end; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 45 页 - - - - - - - - - 也就是说返回的是function ,进入的是procedure。当使用字符串
18、的时候( WideString),对应的为 BSTR。为了达到这个目的,在建立属性的时候,要注意:Get:Type-BSTR Parameters-删除set: Type-Void Parameters-Value BSTR in 这样就能造成上面的效果。refresh-刷新形成程序的框架,并在框架中写入自己的内容:具体处理的程序可以这样写:var Username:string; function TMyShows.Get_name: WideString; begin Result := WideString(Username); end; procedure TMyShows.Set_n
19、ame(const Value: WideString); begin Username := String(Value); end; 关于方法,去掉返回值就是过程,否则是函数:procedure TMyShows.helloName; begin showmessage(您的名字是:+ Username); end; 这里要注意一个问题,messagebox(0,mb_ok)和 showmessage() 需要 Dialogs 库,需要把它Uses 进来。完成的源程序如下:- unit Unit1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - -
20、 - - - - - 名师精心整理 - - - - - - - 第 8 页,共 45 页 - - - - - - - - - $WARN SYMBOL_PLATFORM OFF interface uses Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl,Dialogs; type TMyShows = class(TTypedComObject, IMyShows) protected function Get_name: WideString; stdcall; procedure Set_name(const Value:
21、WideString); stdcall; procedure helloName; stdcall; end; implementation uses ComServ; var Username:string; function TMyShows.Get_name: WideString; begin Result := WideString(Username); end; procedure TMyShows.Set_name(const Value: WideString); begin Username := String(Value); end; procedure TMyShows
22、.helloName; begin showmessage(您的名字是:+ Username); end; initialization TTypedComObjectFactory.Create(ComServer, TMyShows, Class_MyShows, ciMultiInstance, tmApartment); end. - File - Save all 保存Project - Build 编译名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 45 页
23、- - - - - - - - - Run - Register ActiveX Server 注册3)注册和注销组件使用 COM 组件以前, 先要确认它在计算机上是可以使用的,所以必须注册, 注册 DLL 有两种方法:1 在 delphi 中编译 DLL ,编译的同时自动在所编译的计算机上注册,(文件- 生成工程.DLL ) 。2使用Regsvr32.exe(在 Windowssystem 中,或 WINNTsystem32 中 ) ,方法: Windows开始- 运行Regsvr32/s .DLL - 注册Regsvr32/u .DLL - 注销比如上面的例子:Regsvr32 “ d:M
24、yShow Helloname.dll”注册是注册在系统注册表中,所以也可以用regedit.exe 来查看, 对于注销组件, 可以在系统注册表中删除该组件的引用,然后再删除该组件的DLL 或 EXE 文件。注意: COM 类的注册表条目位于系统注册表的HKEY_CLASSES_ROOT中。四、在 .NET 中应用 COM 组件首先建立一个Windows 工程。Project1.MyShow obj=new Project1.MyShowClass(); private void Form1_Load(object sender, System.EventArgs e) 名师资料总结 - -
25、-精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 45 页 - - - - - - - - - private void button1_Click(object sender, System.EventArgs e) obj.Name=textBox1.Text; private void button2_Click(object sender, System.EventArgs e) obj.HelloName(); 可以看出来,和普通的类使用上是一样的。五、 Activex 控件Acti
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 应用COM和接口可用 2022 应用 COM 接口 可用
限制150内