现在的位置: 首页 > 综合 > 正文

COM工作过程示意(一):进程内组件

2013年08月02日 ⁄ 综合 ⁄ 共 1946字 ⁄ 字号 评论关闭

 

这不算一篇纯粹的原创作品,这是我对《COM原理及应用》的一点整理。欢迎发表评论,当然还有后续。

Client

COM

ComponentDLL

CoInitialize(NULL),每个线程都得来一次,初始化该线程COM库。

 

我知道要调用组件的名称叫“Dictionary.Object”,

但我得知道这个名称对应的CLSID,所以我调用CLSIDFromProgID("Dictionary.Object",&clsid)来获取。

 

 

 

 

有了CLSID,我现在就想操作组件,所以我要创建一个组件的对象,其实我并不关心这个对象的具体创建的过程,可能这个对象已经存在,可能还要加载,但我并不关心,这一切对我来说是透明的,我的“创建”办法就是先获得生产这个对象的“工厂”:CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClf);我所要得到的是这个组件对象的指针,也就是pClf

 

 

 

 

 

 

 

 

 

 

 

 

其实我也知道,刚刚这步获得的只是工厂,还不是真正的对象,现在得用这个工厂创建一个真正的对象了。pClf->CreateInstance(NULL, IID_IUnknown, (void **)&pUnknown);

 

 

 

 

 

对象创建起来了,工厂没什么用了,释放它,pClf->Release();pUnknown有值了,这才是我想要的,现在,通过pUnknown做该做的事情吧。

 

怎么做?简单,事先我已经知道了这个接口“IDictionary”,所以pUnknown->QueryInterface (IID_Dictionary, (void **) &pDictionary); pDictionary是我真正要使用的东西。

pDictionary->GetAWord(…);

 

pDictionary->SpellCheck(…);

 

好了,用完了,做事情要有头有尾,Release,调用了多少次QueryInterface()对应Release()。如上例,应该调用pDictionary->Release()

 

当然了,确定pUnknown不再使用之后也得ReleasepUnknown->Release()

 

 

 

 

COM库一阵子不做事情了,现在给点东西它做。我调CoFreeUnusedLibraries()

 

 

 

 

 

 

CoUninitialize(),对应开头的CoInitialize()

 

 

Ready

 

 

 

 

CLSIDFromProgID是我COM库的一个函数,其实我要做的事情就是从注册表中找出“Dictionary.Object”CLSID,然后返回给Client

 

 

 

 

 

 

 

 

好吧,让我看看,嗯,你要的组件对应DictComp.dll这个文件,还没被加载,我现在CoLoadLibrary它(MSDN上说CoGetClassObject并不调用CoLoadLibrary,我没怎么看明白,希望知情人解释一下。)。我一视同仁,加载完毕后调用这个dll的导出函数“DllGetClassObject”。

 

 

 

 

这一步我就“无为”吧,直接把IClassFactory返回给Client

 

 

 

 

(悄悄话:Client直接掉用pClf的方法,则回可没通过我的处理)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

好,我调ComponentDllCanUnloadNow

 

 

 

 

Component那边返回TRUECoFreeLibrary它吧。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

终于轮到我了,DllGetClassObject是我的函数,根据Microsoft这套规范,我实现了工厂类CDictionaryFactory,现在我创建这么一个工厂类,把它的接口IClassFactory返回给COM库。

 

 

 

 

 

 

 

 

我的工厂的“CreateInstance”被Client调用,OK,我来new一个CDictionary吧,并返回它的指针IUnknown

 

 

 

 

 

 

 

 

 

返回一个单词的。

 

检查单词拼写。

 

 

 

收到收到,CDictionary对象的ref--

 

 

收到,由于pUnknown也是指向CDictionary对象,所以还是,CDictionary对象的ref--

(悄悄话:每次ref--,我都会检查ref是否为0,如果是,则删除该CDictionary对象)

 

 

 

DllCanUnloadNow()是我导出的一个函数,用这个函数检查我这个模块是不是所有的对象都被delete了?如果是,那我的使命就结束了,我就可以被T出内存了。

 

 

 

抱歉!评论已关闭.