版权声明:本文为博主原创文章,未经博主允许不得转载。
- CoCreateInstance(....)
- {
- //.......
- IClassFactory *pClassFactory=NULL;
- CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
- pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
- pClassFactory->Release();
- //........
- }
CoCreateInstance(....)
{
//.......
IClassFactory *pClassFactory=NULL;
CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
pClassFactory->Release();
//........
}
这段话的意思就是先得到类厂对象,再通过类厂创建组件从而得到IUnknown指针。继续深入一步,看看CoGetClassObject的内部伪码:
- CoGetClassObject(.....)
- {
- //通过查注册表CLSID_Object,得知组件DLL的位置、文件名
- //装入DLL库
- //使用函数GetProcAddress(...)得到DLL库中函数DllGetClassObject的函数指针。
- //调用DllGetClassObject
- }
- /// DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
- /// 下面是DllGetClassObject的伪码:
- DllGetClassObject(...)
- {
- //......
- CFactory* pFactory= new CFactory; //类厂对象
- pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
- //查询IClassFactory指针
- pFactory->Release();
- //......
- }
- /// CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
- CFactory::CreateInstance(.....)
- {
- //...........
- CObject *pObject = new CObject; //组件对象
- pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
- pObject->Release();
- //...........
- }
CoGetClassObject(.....)
{
//通过查注册表CLSID_Object,得知组件DLL的位置、文件名
//装入DLL库
//使用函数GetProcAddress(...)得到DLL库中函数DllGetClassObject的函数指针。
//调用DllGetClassObject
}
/// DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
/// 下面是DllGetClassObject的伪码:
DllGetClassObject(...)
{
//......
CFactory* pFactory= new CFactory; //类厂对象
pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
//查询IClassFactory指针
pFactory->Release();
//......
}
/// CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
CFactory::CreateInstance(.....)
{
//...........
CObject *pObject = new CObject; //组件对象
pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
pObject->Release();
//...........
}
这部分我们将构造一个创建COM组件的最小框架结构,然后看一看其内部处理流程是怎样的
- IUnknown *pUnk=NULL;
- IObject *pObject=NULL;
- CoInitialize(NULL);
- CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);
- pUnk->QueryInterface(IID_IOjbect, (void**)&pObject);
- pUnk->Release();
- pObject->Func();
- pObject->Release();
- CoUninitialize();
IUnknown *pUnk=NULL;
IObject *pObject=NULL;
CoInitialize(NULL);
CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);
pUnk->QueryInterface(IID_IOjbect, (void**)&pObject);
pUnk->Release();
pObject->Func();
pObject->Release();
CoUninitialize();
- CoCreateInstance(....)
- {
- .......
- IClassFactory *pClassFactory=NULL;
- CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
- pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
- pClassFactory->Release();
- ........
- }
CoCreateInstance(....)
{
.......
IClassFactory *pClassFactory=NULL;
CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
pClassFactory->Release();
........
}
这就是一个典型的创建COM组件的框架,不过我的兴趣在CoCreateInstance身上,让我们来看看它内部做了一些什么事情。以下是它内部实现的一个伪代码:
- CoGetClassObject(.....)
- {
- //通过查注册表CLSID_Object,得知组件DLL的位置、文件名
- //装入DLL库
- //使用函数GetProcAddress(...)得到DLL库中函数DllGetClassObject的函数指针。
- //调用DllGetClassObject
- }
- DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
- 下面是DllGetClassObject的伪码:
- DllGetClassObject(...)
- {
- ......
- CFactory* pFactory= new CFactory; //类厂对象
- pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
- //查询IClassFactory指针
- pFactory->Release();
- ......
- }
- CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
- CFactory::CreateInstance(.....)
- {
- ...........
- CObject *pObject = new CObject; //组件对象
- pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
- pObject->Release();
- ...........
- }
CoGetClassObject(.....)
{
//通过查注册表CLSID_Object,得知组件DLL的位置、文件名
//装入DLL库
//使用函数GetProcAddress(...)得到DLL库中函数DllGetClassObject的函数指针。
//调用DllGetClassObject
}
DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
下面是DllGetClassObject的伪码:
DllGetClassObject(...)
{
......
CFactory* pFactory= new CFactory; //类厂对象
pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
//查询IClassFactory指针
pFactory->Release();
......
}
CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
CFactory::CreateInstance(.....)
{
...........
CObject *pObject = new CObject; //组件对象
pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
pObject->Release();
...........
}
这段话的意思就是先得到类厂对象,再通过类厂创建组件从而得到IUnknown指针。继续深入一步,看看CoGetClassObject的内部伪码:
上图是从COM+技术内幕中COPY来的一个例图,从图中可以清楚的看到CoCreateInstance的整个流程。
(7) 一个典型的自注册的COM DLL所必有的四个函数
DllGetClassObject:用于获得类厂指针
DllRegisterServer:注册一些必要的信息到注册表中
DllUnregisterServer:卸载注册信息
DllCanUnloadNow:系统空闲时会调用这个函数,以确定是否可以卸载DLL
DLL还有一个函数是DllMain,这个函数在COM中并不要求一定要实现它,但是在VC生成的组件中自动都包含了它,它的作用主要是得到一个全局的实例对象。
(8) 注册表在COM中的重要作用
首先要知道GUID的概念,COM中所有的类、接口、类型库都用GUID来唯一标识,GUID是一个128位的字串,根据特制算法生成的GUID可以保证是全世界唯一的。 COM组件的创建,查询接口都是通过注册表进行的。有了注册表,应用程序就不需要知道组件的DLL文件名、位置,只需要根据CLSID查就可以了。当版本升级的时侯,只要改一下注册表信息就可以神不知鬼不觉的转到新版本的DLL。
-
顶
- 4
-
踩
- 1
- 上一篇Windows编程命名规则(转)
- 下一篇C语言可变参数函数探秘
我的同类文章
- •使用COM简单操作IE2013-06-10
- •Inside COM读书笔记-----多线程2013-05-22
- •Inside COM读书笔记-----ExE中的服务器2013-05-22
- •Inside COM读书笔记-----类厂2013-05-14
- •Inside COM读书笔记------动态链接库2013-05-13
- •Inside COM读书笔记------QueryInterface接口2013-05-13
- •COM的“可重用性”特性包括两种模型:包容和聚合2013-05-28
- •Inside COM读书笔记-----调度接口与自动化2013-05-22
- •Inside COM读书笔记-----包容和聚合2013-05-22
- •Inside COM读书笔记-----关于HRESULT、GUID、注册表及其它细节2013-05-13
- •Inside COM读书笔记------引用计数2013-05-13