COM杂谈(一)

来源:互联网 发布:卡片战斗先导之all爱知 编辑:程序博客网 时间:2024/05/17 01:35

由于工作需要,最近开始忙于C#跟COM的交互操作。之前基本上没有玩过C#跟COM,作为一名狂热的技术民工表示,越高级越好玩。即将上市的Windows Phone 7的SDK是基于Silverlight的,用C#作为其编程语言。据我初步的关注了一下,跟Palm的web os有几分神似,主要的应用软件层都是基于Browser。web os比较纯粹,就是Browser上面的HTML+JS,而WPhone7则是则是通过Silverlight的plugin来嵌入到Browser,殊途同归。他们的一个共同点就是都是managed code,因此彼此都面临着如何调用native的代码。之前做web os开发的时候是利用NPAPI来写插件,通过插件来调用。当然还有ActiveX的方式。WPhone7的Silverlight要调native代码的话,可以用silverlight提供的javascript api,同样用插件的形式,也可以通过COM接口。

 

COM最好的学习资料莫过于《COM本质》,该讲的都讲了,它比较好的一个方面就是先一步步的介绍为什么要COM,为什么COM是现在这个样子,这样不至于显得太突兀,太死板。与其说COM是一种技术,不如说是一种设计模式,它提供了一种标准式接口来作为软件的复用。学COM就是要用一种软件复用的设计思想来理解。

 

COM的所有对象都继承自一个标准的接口类 IUnknown,有三个基本接口AddRef, Release, QueryInterface。就是这些标准的接口函数,使得COM的技术可以跨语言,可以用VB,C#来利用C++写的COM对象。前面两个接口函数是引用计数,第三个是重点,它根据一个接口ID来查找获得对应的接口对象。 

 

进程内COM

 

COM的复用可以分为两种,一是进程内的,通过DLL来提供接口,把该DLL动态加载到需要使用该组件的进程空间内。二是进程外的,通过外部的EXE来提供接口,这种方式需要进程间通信。

 

进程内的COM是比较灵活的,你可以用很多种方式来加载DLL到进程空间,从而利用该COM DLL提供COM对象。

 

利用注册表来查找COM DLL: 这种方式是利用windows的一些标准接口来实现。关键词 CoCreateInstance,CoGetClassObject,DllGetClassObject。 下面一步一步的介绍如何利用这些标准的API来生成你的COM对象。写个COM的HelloCom。

 

HelloComServer:

 

一. 建一个DLL工程。先定义自己的COM接口

 

HelloComServer.h

 

 

HelloComServer.cpp

 

  

 

二,导出DllGetClassObject接口函数,系统会通过这个接口来生成COM对象,当然得自己实现这个函数。

 

HelloComServer.cpp

 

 

 

通过一个Module定义文件来把上面这个函数导出,把HelloComServer.def加入工程的linker选项的Input->Module Definition File

 

HelloComServer.def

 

 

 三,把该COM DLL写进注册表.

生成下面的 HelloComServer.reg注册表函数(%HelloComServerDLL%为HelloComServer.dll的pathname)

 

HelloComServer.reg

 

OK, 一个简单的COM Server Dll就写好了,剩下的就是写一个Client程序来调用这个COM接口了。 

 

 HelloComClient.cpp

 

 

 OK, 一个最简单的COM调用就完成了。注意这里只能用CoGetClassObject,而不能用CoCreateInstance,因为CoCreateInstance是需要用Factory机制来生成COM对象。

CoCreateInstance是先做一次CoGetClassObject(rclsid, dwClsContext, NULL, IID_IClassFactory, &pCF); 得到一个ClassFactory的实例,然后再做一次pCF->CreateInstance(pUnkOuter, riid, ppvObj),来获得对应riid的借口的对象。因此如果你必须要自己实现Factory机制,否则会找不到对应的COM对象。需要对上面的代码做如下改动。

 

加入ClassFactory实现

 

HelloComServer.cpp

 

 修改DllGetClassObject导出函数

 

HelloComServer.cpp

 

 

 

修改之后的代码就可以用CoCreateInstance来创建COM对象了。

原创粉丝点击