- 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(.....)
- {
-
-
-
-
- }
-
-
- DllGetClassObject(...)
- {
-
-
CFactory*pFactory=newCFactory;
-
pFactory->QueryInterface(IID_IClassFactory,(void**)&pClassFactory);
-
- pFactory->Release();
-
- }
-
- CFactory::CreateInstance(.....)
- {
-
-
CObject*pObject=newCObject;
-
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(.....)
- {
-
-
-
-
- }
- DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
- 下面是DllGetClassObject的伪码:
- DllGetClassObject(...)
- {
- ......
-
CFactory*pFactory=newCFactory;
-
pFactory->QueryInterface(IID_IClassFactory,(void**)&pClassFactory);
-
- pFactory->Release();
- ......
- }
- CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
- CFactory::CreateInstance(.....)
- {
- ...........
-
CObject*pObject=newCObject;
-
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。
分享到:
相关推荐
- 实现接口:为接口提供具体的实现,这些实现包含了插件的核心功能。 - 注册组件:通过注册表将COM组件的信息告知系统,使其能够在运行时被找到和加载。 - 加载和使用:Word通过CoCreateInstance函数实例化插件,...
包容实现(Aggregation)是一种特殊的COM对象组合方式,它允许一个COM对象(容器对象)包含另一个COM对象(组件对象),并将组件对象的接口暴露给自己,使得外部调用者仿佛直接与容器对象交互,但实际上操作的是内部...
1. 封装性:接口定义了组件对外暴露的服务,通过多接口,组件可以更好地隐藏内部实现细节,增强封装性。 2. 扩展性:添加新接口即可扩展组件功能,无需修改已有的接口或客户端代码。 3. 互操作性:多接口设计使得...
这一特性极大地简化了应用程序的开发过程,使得开发者无需深入了解特定数据库系统的内部结构和访问协议。 #### 三、DMOLEDBProvider 概览 **DMOLEDBProvider** 是武汉华工达梦数据库公司为了实现达梦数据库与 OLE ...
它们可以通过接口进行交互,而无需关心内部实现细节,从而提高了代码的复用性和可维护性。COM组件具有二进制兼容性,使得不同编程语言和工具开发的组件能够无缝协作。 在组态软件开发中,COM技术扮演了至关重要的...
组件通过接口与外界交互,隐藏其内部实现细节。 3. **类工厂(Class Factory)**:创建COM对象的工厂类,用于生成接口的实例。`IClassFactory`接口提供了`CreateInstance`方法来实例化对象。 4. **引用计数...
COM对象是独立的、可重用的软件模块,可以通过接口进行交互,而无需知道对象的具体实现。这实现了代码的封装和解耦,提高了软件的可维护性和可扩展性。 2. **MFC与COM的关系**:MFC库提供了一套面向对象的类,用于...
你可以通过编译和运行该项目,查看其具体实现细节,包括如何加载滤镜,如何处理命令行参数,以及如何管理DirectShow接口和方法。 为了提高播放器的功能,你还可以添加额外的特性,如音视频同步、播放控制(暂停、...
每个接口都是一系列方法的集合,这些方法在组件内部实现。接口使用纯虚函数定义,并使用`DECLARE_INTERFACE_`或`DECLAREPUREINTERFACE`宏来声明。 2. **实现IUnknown接口**:所有COM组件都必须实现IUnknown接口,它...
### ATL揭秘之“对象创建”篇 当我们使用Visual C++的ATL...它隐藏了对象创建的具体细节,允许开发者专注于业务逻辑而不必担心底层实现。通过理解ATL的工作原理,我们可以更好地利用其功能,提高开发效率和代码质量。
例如,你可以创建一个`CMFCFileOpener`类,包含`OpenWordFile`、`OpenPPTFile`和`OpenPDFFile`成员函数,每个函数内部实现对应的文件打开逻辑。 为了实现这些功能,开发者需要对COM编程有基本的理解,同时还需要...
COM组件通过接口与外界交互,这样设计的好处在于,调用者无需关心组件内部的具体实现,只需知道接口定义即可。 COM组件的创建通常包括以下几个步骤: 1. 定义接口:接口定义了组件对外提供的服务,是纯虚函数的集合...
这种设计使得组件可以在不关心对方具体实现的情况下进行协作,提高了软件的可复用性和可扩展性。 COM组件通过接口ID(IID)进行识别,每个接口都有一个全局唯一的标识符。同时,组件实例由CLSID(Class ID)标识,...
COM对象是具有标准接口的二进制组件,可以被其他应用程序调用,无需知道其内部实现细节。在处理Excel时,我们可以使用Microsoft Office提供的COM接口,如Excel.Application,来控制Excel程序并操作工作簿和工作表。 ...
这些对象可以通过接口提供服务,使得其他应用程序可以通过标准的COM接口调用这些服务,而无需了解内部实现细节。这种设计模式有助于提高代码的可维护性和可扩展性。 在"COM编程精彩实例"中,可能包含了各种实际应用...
一个良好的接口应该清晰、简洁,只暴露必要的功能,隐藏内部实现细节。在Delphi中,接口常通过`interface`关键字定义,使用`uses`引入所需单元,然后声明方法和属性。例如: ```delphi unit MyDLLInterface; ...
`CoCreateInstance`函数是COM中创建对象实例的主要方式之一,了解其内部机制有助于更好地控制对象的生命周期。 #### 十一、COM服务器注册 **1. 注册过程**:通过编辑注册表或者使用`Regsvr32.exe`工具完成注册。 *...
具体实现过程中,开发者可能会遇到以下步骤: - 引入必要的COM库和头文件,例如`#import`或`CoCreateInstance`来创建COM对象。 - 实现类的构造函数,初始化COM组件并获取IIS管理接口。 - 设计类的方法,如`...
COM组件的核心思想是“二进制兼容性”,它定义了一种标准接口,使得组件可以在不考虑其内部实现的情况下被其他程序调用。这种接口独立性使得开发者可以创建可重用的代码模块,而无需关心这些模块是如何被实现的。COM...
COM 提供了一种标准接口,使得软件组件可以独立于具体的实现语言、操作系统环境和硬件平台运行。《COM本质论》是由知名IT作者侯捷编著的一本深入探讨COM技术的专业书籍,书中不仅理论详尽,而且配以丰富的实践代码,...