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(); //........... }
这部分我们将构造一个创建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();
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(); ........... }
这段话的意思就是先得到类厂对象,再通过类厂创建组件从而得到IUnknown指针。继续深入一步,看看CoGetClassObject的内部伪码:
上图是从COM+技术内幕中COPY来的一个例图,从图中可以清楚的看到CoCreateInstance的整个流程。
(7) 一个典型的自注册的COM DLL所必有的四个函数
DllGetClassObject:用于获得类厂指针
DllRegisterServer:注册一些必要的信息到注册表中
DllUnregisterServer:卸载注册信息
DllCanUnloadNow:系统空闲时会调用这个函数,以确定是否可以卸载DLL
DLL还有一个函数是DllMain,这个函数在COM中并不要求一定要实现它,但是在VC生成的组件中自动都包含了它,它的作用主要是得到一个全局的实例对象。
上图是从COM+技术内幕中COPY来的一个例图,从图中可以清楚的看到CoCreateInstance的整个流程。
(8) 注册表在COM中的重要作用
首先要知道GUID的概念,COM中所有的类、接口、类型库都用GUID来唯一标识,GUID是一个128位的字串,根据特制算法生成的GUID可以保证是全世界唯一的。 COM组件的创建,查询接口都是通过注册表进行的。有了注册表,应用程序就不需要知道组件的DLL文件名、位置,只需要根据CLSID查就可以了。当版本升级的时侯,只要改一下注册表信息就可以神不知鬼不觉的转到新版本的DLL。
参考了 http://blog.csdn.net/wangqiulin123456/article/details/8210673
相关推荐
- 实现接口:为接口提供具体的实现,这些实现包含了插件的核心功能。 - 注册组件:通过注册表将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技术的专业书籍,书中不仅理论详尽,而且配以丰富的实践代码,...