`
chinamming
  • 浏览: 150268 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

CoCreateInstance具体内部实现

 
阅读更多
  1. CoCreateInstance(....)
  2.     {
  3.     //.......
  4.     IClassFactory*pClassFactory=NULL;
  5.     CoGetClassObject(CLSID_Object,CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory,(void**)&pClassFactory);
  6.     pClassFactory->CreateInstance(NULL,IID_IUnknown,(void**)&pUnk);
  7.     pClassFactory->Release();
  8.     //........
  9.    }

  这段话的意思就是先得到类厂对象,再通过类厂创建组件从而得到IUnknown指针。继续深入一步,看看CoGetClassObject的内部伪码:

   
  1. CoGetClassObject(.....)
  2.    {
  3.     //通过查注册表CLSID_Object,得知组件DLL的位置、文件名
  4.     //装入DLL库
  5.     //使用函数GetProcAddress(...)得到DLL库中函数DllGetClassObject的函数指针。
  6.     //调用DllGetClassObject
  7.    }
  8.    /// DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
  9.    /// 下面是DllGetClassObject的伪码:
  10.     DllGetClassObject(...)
  11.     {
  12.     //......
  13.     CFactory*pFactory=newCFactory;//类厂对象
  14.     pFactory->QueryInterface(IID_IClassFactory,(void**)&pClassFactory);
  15.     //查询IClassFactory指针
  16.     pFactory->Release();
  17.     //......
  18.     }
  19.    /// CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
  20.     CFactory::CreateInstance(.....)
  21.     {
  22.     //...........
  23.     CObject*pObject=newCObject;//组件对象
  24.     pObject->QueryInterface(IID_IUnknown,(void**)&pUnk);
  25.     pObject->Release();
  26.     //...........
  27.     }

这部分我们将构造一个创建COM组件的最小框架结构,然后看一看其内部处理流程是怎样的

  1.     IUnknown*pUnk=NULL;
  2.     IObject*pObject=NULL;
  3.     CoInitialize(NULL);
  4.     CoCreateInstance(CLSID_Object,CLSCTX_INPROC_SERVER,NULL,IID_IUnknown,(void**)&pUnk);
  5.     pUnk->QueryInterface(IID_IOjbect,(void**)&pObject);
  6.     pUnk->Release();
  7.     pObject->Func();
  8.     pObject->Release();
  9.     CoUninitialize();


  1. CoCreateInstance(....)
  2.  {
  3.     .......
  4.     IClassFactory*pClassFactory=NULL;
  5.     CoGetClassObject(CLSID_Object,CLSCTX_INPROC_SERVER,NULL,IID_IClassFactory,(void**)&pClassFactory);
  6.     pClassFactory->CreateInstance(NULL,IID_IUnknown,(void**)&pUnk);
  7.     pClassFactory->Release();
  8.     ........
  9.  }

  这就是一个典型的创建COM组件的框架,不过我的兴趣在CoCreateInstance身上,让我们来看看它内部做了一些什么事情。以下是它内部实现的一个伪代码:

  1.   CoGetClassObject(.....)
  2.    {
  3.     //通过查注册表CLSID_Object,得知组件DLL的位置、文件名
  4.     //装入DLL库
  5.     //使用函数GetProcAddress(...)得到DLL库中函数DllGetClassObject的函数指针。
  6.     //调用DllGetClassObject
  7.    }
  8.     DllGetClassObject是干什么的,它是用来获得类厂对象的。只有先得到类厂才能去创建组件.
  9.     下面是DllGetClassObject的伪码:
  10.     DllGetClassObject(...)
  11.     {
  12.     ......
  13.     CFactory*pFactory=newCFactory;//类厂对象
  14.     pFactory->QueryInterface(IID_IClassFactory,(void**)&pClassFactory);
  15.     //查询IClassFactory指针
  16.     pFactory->Release();
  17.     ......
  18.     }
  19.     CoGetClassObject的流程已经到此为止,现在返回CoCreateInstance,看看CreateInstance的伪码:
  20.     CFactory::CreateInstance(.....)
  21.     {
  22.     ...........
  23.     CObject*pObject=newCObject;//组件对象
  24.     pObject->QueryInterface(IID_IUnknown,(void**)&pUnk);
  25.     pObject->Release();
  26.     ...........
  27.     }

  这段话的意思就是先得到类厂对象,再通过类厂创建组件从而得到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。

分享到:
评论

相关推荐

    Word2000&XP中内部COM插件的编程实现

    - 实现接口:为接口提供具体的实现,这些实现包含了插件的核心功能。 - 注册组件:通过注册表将COM组件的信息告知系统,使其能够在运行时被找到和加载。 - 加载和使用:Word通过CoCreateInstance函数实例化插件,...

    最简单的COM实现 - 包容实现

    包容实现(Aggregation)是一种特殊的COM对象组合方式,它允许一个COM对象(容器对象)包含另一个COM对象(组件对象),并将组件对象的接口暴露给自己,使得外部调用者仿佛直接与容器对象交互,但实际上操作的是内部...

    COM组件中实现多接口

    1. 封装性:接口定义了组件对外暴露的服务,通过多接口,组件可以更好地隐藏内部实现细节,增强封装性。 2. 扩展性:添加新接口即可扩展组件功能,无需修改已有的接口或客户端代码。 3. 互操作性:多接口设计使得...

    ole db教程

    这一特性极大地简化了应用程序的开发过程,使得开发者无需深入了解特定数据库系统的内部结构和访问协议。 #### 三、DMOLEDBProvider 概览 **DMOLEDBProvider** 是武汉华工达梦数据库公司为了实现达梦数据库与 OLE ...

    基于COM技术的组态软件研究与实现

    它们可以通过接口进行交互,而无需关心内部实现细节,从而提高了代码的复用性和可维护性。COM组件具有二进制兼容性,使得不同编程语言和工具开发的组件能够无缝协作。 在组态软件开发中,COM技术扮演了至关重要的...

    计算机软件-编程源码-com对象的实现实例.zip

    组件通过接口与外界交互,隐藏其内部实现细节。 3. **类工厂(Class Factory)**:创建COM对象的工厂类,用于生成接口的实例。`IClassFactory`接口提供了`CreateInstance`方法来实例化对象。 4. **引用计数...

    一个用mfc实现的时钟COM元件

    COM对象是独立的、可重用的软件模块,可以通过接口进行交互,而无需知道对象的具体实现。这实现了代码的封装和解耦,提高了软件的可维护性和可扩展性。 2. **MFC与COM的关系**:MFC库提供了一套面向对象的类,用于...

    DirectShow播放视频文件的命令行简单实现

    你可以通过编译和运行该项目,查看其具体实现细节,包括如何加载滤镜,如何处理命令行参数,以及如何管理DirectShow接口和方法。 为了提高播放器的功能,你还可以添加额外的特性,如音视频同步、播放控制(暂停、...

    com原理与应用 代码

    每个接口都是一系列方法的集合,这些方法在组件内部实现。接口使用纯虚函数定义,并使用`DECLARE_INTERFACE_`或`DECLAREPUREINTERFACE`宏来声明。 2. **实现IUnknown接口**:所有COM组件都必须实现IUnknown接口,它...

    ATL 揭秘之“对象创建”篇

    ### ATL揭秘之“对象创建”篇 当我们使用Visual C++的ATL...它隐藏了对象创建的具体细节,允许开发者专注于业务逻辑而不必担心底层实现。通过理解ATL的工作原理,我们可以更好地利用其功能,提高开发效率和代码质量。

    MFC 打开word、ppt、pdf文件

    例如,你可以创建一个`CMFCFileOpener`类,包含`OpenWordFile`、`OpenPPTFile`和`OpenPDFFile`成员函数,每个函数内部实现对应的文件打开逻辑。 为了实现这些功能,开发者需要对COM编程有基本的理解,同时还需要...

    Com编程指南

    COM组件通过接口与外界交互,这样设计的好处在于,调用者无需关心组件内部的具体实现,只需知道接口定义即可。 COM组件的创建通常包括以下几个步骤: 1. 定义接口:接口定义了组件对外提供的服务,是纯虚函数的集合...

    COM原理与应用源码

    这种设计使得组件可以在不关心对方具体实现的情况下进行协作,提高了软件的可复用性和可扩展性。 COM组件通过接口ID(IID)进行识别,每个接口都有一个全局唯一的标识符。同时,组件实例由CLSID(Class ID)标识,...

    VS2005处理EXCEL

    COM对象是具有标准接口的二进制组件,可以被其他应用程序调用,无需知道其内部实现细节。在处理Excel时,我们可以使用Microsoft Office提供的COM接口,如Excel.Application,来控制Excel程序并操作工作簿和工作表。 ...

    65943103com_Samples-1_动态链接库深入浅出_vc++_

    这些对象可以通过接口提供服务,使得其他应用程序可以通过标准的COM接口调用这些服务,而无需了解内部实现细节。这种设计模式有助于提高代码的可维护性和可扩展性。 在"COM编程精彩实例"中,可能包含了各种实际应用...

    Delphi中的DLL封装和调用对象技术.pdf

    一个良好的接口应该清晰、简洁,只暴露必要的功能,隐藏内部实现细节。在Delphi中,接口常通过`interface`关键字定义,使用`uses`引入所需单元,然后声明方法和属性。例如: ```delphi unit MyDLLInterface; ...

    COM变成入门资料

    `CoCreateInstance`函数是COM中创建对象实例的主要方式之一,了解其内部机制有助于更好地控制对象的生命周期。 #### 十一、COM服务器注册 **1. 注册过程**:通过编辑注册表或者使用`Regsvr32.exe`工具完成注册。 *...

    IIS配置类

    具体实现过程中,开发者可能会遇到以下步骤: - 引入必要的COM库和头文件,例如`#import`或`CoCreateInstance`来创建COM对象。 - 实现类的构造函数,初始化COM组件并获取IIS管理接口。 - 设计类的方法,如`...

    COM组件应用于设计(转发)源代码

    COM组件的核心思想是“二进制兼容性”,它定义了一种标准接口,使得组件可以在不考虑其内部实现的情况下被其他程序调用。这种接口独立性使得开发者可以创建可重用的代码模块,而无需关心这些模块是如何被实现的。COM...

    com本质论这本著名书籍的源代码

    COM 提供了一种标准接口,使得软件组件可以独立于具体的实现语言、操作系统环境和硬件平台运行。《COM本质论》是由知名IT作者侯捷编著的一本深入探讨COM技术的专业书籍,书中不仅理论详尽,而且配以丰富的实践代码,...

Global site tag (gtag.js) - Google Analytics