随笔 - 20, 文章 - 0, 评论 - 45, 引用 - 0
数据加载中……

创建COM组件的全过程分析

一、简单介绍创建COM组件的过程     
      在创建COM组件之前,首先必须调用CoInitialize(NULL)初始化COM库,这个函数的解释为:Initializes the COM library on the current thread and identifies the concurrency model as single-thread apartment (STA).
      接着,就可以通过调用CoCreateInstance函数创建COM组件对象。
      当不再使用COM库时,需要调用CoUninitialize()释放COM库。这个函数的解释为:Closes the COM library on the current thread, unloads all DLLs loaded by the thread, frees any other resources that the thread maintains。
二、详细分析CoCreateInstance的具体操作
 1)CoCreateInstance作用为:Creates a single uninitialized object of the class associated with a specified CLSID.
       函数的声明即参数解释如下:
STDAPI CoCreateInstance(
  REFCLSID rclsid,     
//[in] 用来唯一标识一个对象的CLSID(128位),需要用它来创建指定对象。 
  LPUNKNOWN pUnkOuter, //[in] 如果为NULL, 表明此对象不是聚合式对象一部分。如果不是NULL, 则指针指向一个聚合式对象的IUnknown接口。 
  DWORD dwClsContext,  //[in] 组件类别. 可使用CLSCTX枚举器中预定义的值. 
  REFIID riid,         //Reference to the identifier of the interface,接口的唯一标识符
  LPVOID * ppv         //Address of output variable that receives the interface pointer requested in riid,用接口指针指向创建的对象。
);

2)COM组件实际上是一个C++类,对于组件的外部使用者来说,这个类名一般不可知,那么如何创建这个类的实例?每个组件都必须实现一个与之相对应的类工厂,在类工厂的接口函数CreateInstance中,才能使用new操作生成一个COM组件类的对象实例。那么如何获得类工厂对象呢?每个COM组件都使用一个guid类唯一标识。当创建一个COM组件时,总是首先获得guid。然后通过这个guid调用CoGetClassObject获得COM组件对象对应的类工厂。
CoCreateInstance的实现伪代码:
CoCreateInstance(CLSID_Object,NULL,CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&pUnk)
{
// Do something ...
IClassFactory * pClassFactory = NULL;
CoGetClassObject(CLSID_Object,NULL,CLSCTX_INPROC_SERVER,IID_IClassFactory,(
void**)&pClassFactory );//通过COM组件的guid类获得这个组件的类工厂对象接口。
pClassFactory->CreateInstance(NULL,IID_IUnknown,(void**)&pUnk); //通过COM组件的guid创建COM组件对象。
pClassFactory
->Release();
//...
}

在以下源码中,DllGetClassObject是在COM组件DLL中必须实现的一个导出函数,它的作用是根据指定的组件GUID创建相应的类工厂对象,并返回类工厂的IClassFactory接口,CreateInstance是IClassFactory接口的一个接口方法,负责最终创建组件对象实例,CObject就是我们的COM组件类,它实现了COM框架以外的真正的组件功能。
CoGetClassObject(......)
{
//通过查询注册表CLSID_Object得知组件DLL文件路径
//装入DLL库(调用LoadLibrary)
//使用函数GetProcAddress(......)得到DLL中函数DllGetClassObject的函数指针
//调用DllGetClassObject得到类工厂对象指针
}

DllGetClassObject(...)
{
//...
//创建类工厂对象
CFactory* pFactory = new CFactory;
pFactory
->QueryInterface(IID_IClassFactory,(void**)&pClassFactory);
pFactory
->Release();
//...
}

CFactory::CreateInstance(...)
{
//...
//创建CLSID_Object 对应的组件对象
CObject* pObject = new CObject;
pObject
->QueryInterface(IID_IUnknown,(void**)*pUnk);
pObject
->release();
//...
}

下面是上述创建过程的一个图解:

下面是一个按时间顺序解析的流程图:



参考文献:
1.DirectShow开发指南
2.MSDN
3. COM技术内幕


posted on 2011-04-23 20:44 Kenny Jiang 阅读(2947) 评论(3)  编辑 收藏 引用 所属分类: COM

评论

# re: 创建COM组件的全过程分析  回复  更多评论   

有没有对COM这些的介绍比较到位的书推荐 ?

我的基础是了解C++,了解windows API,MFC的一些原理了解。

使用过一些封装的COM组件,不过都是直接调用,没有编写过。对这个一头雾水。

谢谢了。。。

yjvujj0711#163.com
2011-04-23 21:26 | fazhang

# re: 创建COM组件的全过程分析  回复  更多评论   

@fazhang
COM本质论
COM技术内幕
2011-04-23 21:32 | Kenny Jiang

# re: 创建COM组件的全过程分析  回复  更多评论   

@Kenny Jiang
好的。多谢。CPP这边要申请了才能通过。。。懒得注册了。
2011-04-23 23:18 | fazhang

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理