1.CoCreateInstance

通过传人参数CLSID创建相应组件的一个实例,并返回此组件实例的某个接口。

  • CoCreateInstance的声明

HRESULT __stdcall CoCreateInstance(
      __in REFCLSID rclsid,
      __in_opt LPUNKNOWN pUnkOuter,
      __in DWORD dwClsContext,
      __in REFIID riid,
      __deref_out LPVOID FAR* ppv
      );
有四个输入参数和一个输出参数,第一个参数待创建组件的CLSID,第二个参数用于聚合组件,第三个参数是限定所创建组件的执行上下文。第三个参数组件上待使用的接口IID,最后一个参数返回接口的指针。
  • CoCreateInstance的使用
//Create Component
IX *pIX = NULL;
HRESULT hr = CoCreateInstance(CLSID_Component,
                                    NULL,
                                    CLSCTX_INPROC_SERVER,
                                    IID_IX,
                                    ( void**)&pIX);
if(SUCCEEDED(hr))
{
      pIX->Fx();
      pIX->Release();
}

类上下文

CoCreatInstance第三个参数dwClsContext可以控制所创建的组件是在与客户相同的进程中允许,还是在不同的进程中运行,或者是子啊远程机器上运行。
客户可以在三种不同的上下文中使用某个组件:进程中、本地以及远程。常用组合定义:

2.类厂

CoCreateInstance实际上并没有直接创建COM组件,而是创建一个被称作类厂的组件,再由类厂创建组件,起唯一功能呢就是创建其他的组件。精确的说是某个特定的类厂将创建只同某个特定的CLSID相应的组件。客户可以通过类厂所支持的接口来对类厂创建组件的过程加以控制。创建组件的标准接口是
IClassFactory。
CoGetClassObject
CoCreate接收一个CLSID作为参数并返回指向所创建的组件中的某个接口指针。为创建同某个组件想对应的类厂,需要CoGetClassObject函数。
HRESULT __stdcall CoGetClassObject(
      __in REFCLSID rclsid,
      __in DWORD dwClsContext,
      __in_opt LPVOID pvReserved,
      __in REFIID riid,
      __deref_out LPVOID FAR* ppv);

参数和CoCreateInstance很相似。第一个参数都是组件的CLSID.第二个参数则是创建组件的执行上下文。最后两个参数也想同,CoGetClassObject返回的是指向类厂中某个接口的指针。而CoCreateInstance是返回的指向组件中某个接口的指针。其中pServerInfo指针将被DCOM用于控制对远程组件的访问。
ICalssFactory
 IClassFactory : public IUnknown
    {
    public:
        virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance(
            /* [unique][in] */ IUnknown *pUnkOuter,
            /* [in] */ REFIID riid,
            /* [iid_is][out] */ void **ppvObject) = 0;
       
        virtual /* [local] */ HRESULT STDMETHODCALLTYPE LockServer(
            /* [in] */ BOOL fLock) = 0;
    };
CoCreateInstance与CoGetClassObject的比较
在每次创建组件时,先创建相应的类厂,然后获取IClassFactory指针来创建所需接口比直接调用CoCreateInstance来创建所需的组件要复杂。看下如何用CoGetClassObject实现CoCreateInstance:
HRESULT __stdcall CoCreateInstance(
      __in REFCLSID rclsid,
      __in_opt LPUNKNOWN pUnkOuter,
      __in DWORD dwClsContext,
      __in REFIID riid,
      __deref_out LPVOID FAR* ppv)
{
      *ppv = NULL;
      IClassFactory *pIFactory = NULL;
      HRESULT hr = CoGetClassObject(rclsid,
            dwClsContext,
            NULL,
            IID_IClassFactory,
            ( void**)&pIFactory);
       if (SUCCEEDED(hr))
      {
            hr = pIFactory->CreateInstance(pUnkOuter, riid,ppv);
            pIFactory->Release();
      }
}
可以看到CoCreateInstance首先调用CoGetClassObject来获取类厂中的ICalssFactory接口指针,再通过ICalssFactory::CreateInstance完成新组件的创建。

3.类厂的实现

DllGetClassObject的使用

CoGetClassObject需要DLL中的一个特定函数来创建组件的类厂。此函数就是DllGetClassObject。
HRESULT __stdcall DllGetClassObject(
      __in REFCLSID rclsid,
      __in REFIID riid,
      __deref_out LPVOID FAR* ppv
);
这三个参数和CoGetClassObject的三个参数是相同的,将CLSID传给DllGetClassObject可以是DLL支持任意数目的组件,DllGetClassObject可以用CLSID来选择合适的类厂。

组件的创建过程

首先客户通过CoGetClassObject来启动组件的创建过程。其次是Com库他实现了CoGetClassObject函数,第三是DLL,其中实现了被CoGetClassObject叼哦那个的DllGetClassObject函数,DllGetClassObject函数的任务就是创建客户所请求的类厂。创建玩类厂后客户将使用ICalssFactory接口来创建相应的组件。

4.同一DLL中的多个组件

将待创建的组件CLSID传给DllGetClassObject来创建相应的类厂。

5.DLL的卸载

COM库实现了一个名为CoFreeUnusedLibraries函数以释放哪些不在使用的库,但何时不再使用库呢?CoFreeUnusedLibraries将调用DllCanUnloadNew以询问DLL是否可以被卸载。LockServer给客户提供了一种将服务器保存在内存中,直到使用完毕的方法,客户需要调用LockServer(True)锁住服务器。使用完毕后就可以使用LockServer(False)解锁。

Inside COM读书笔记-----类厂相关推荐

  1. JAVA编程思想——读书笔记 类再生

    文章目录 类再生 1. 组合的语法 对象句柄的初始化 2. 继承的语法 3. 初始化父类 默认构造器 有参构造器 4.合成和继承的结合 5.选择组合还是继承 谨慎使用继承 6.向上转型 7.什么是向上 ...

  2. 《Java核心技术》 -- 读书笔记 ② - 类 | 对象 | 接口

    对象vs对象变量 "对象" 描述的是一个类的具体实例,他被java虚拟机分配在 "堆" (Heap)中. "对象变量" 为一个对象的引用(对 ...

  3. 读书笔记|| 类继承

    一.一个简单的基类 面向对象编程的主要目的之一是提供可重用的代码.传统的C函数库通过预定义.预编译的函数提供了可重用性.C++类提供了更高层次的重用性,类库由类声明和实现构成.因为类组合了数据表示和类 ...

  4. 读书笔记||类和动态内存分配

    一.动态内存和类 C++在分配内存的时候是让程序是在运行时决定内存分配,而不是在编译时再决定.C++使用new和delete运算符来动态控制内存.但是在类中使用这些运算符将导致许多新的编程问题,在这种 ...

  5. Inside COM读书笔记-----包容和聚合

    1.      包容和聚合 包容和聚合实际上是使一个组件使用另一个组件的一种技术. 包容简介 外部组件包含指向内部组件接口的指针,外部组件只是内部组件的一个客户.外部组件也可以通过将调用转发给内部组件 ...

  6. Inside COM读书笔记-----多线程

    1.      COM线程模型 COM并没有定义新的线程和进程模型,而是直接使用Win32线程. 1.1Win32线程 典型的Win32线程具有两种不同类型的线程:用户界面线程和工作线程.用户线程是同 ...

  7. effective java 读书笔记——类和接口

    上周因为准备考试等一堆原因,没空看书,今天补上一点. 类和接口是java程序设计语言的核心,它们也是java语言的基本抽象单元,java语言提供了很多强大的基本元素,供程序员设计类和接口,这一章讲的是 ...

  8. 怎么用思维导图做读书笔记?思维导图这样画

    怎么用思维导图做读书笔记?读书笔记是在读书时记录自己阅读心得,也可以将文中精彩的部分整理出来,一来方便我们对内容进行深入理解,积累并牢固掌握所学到的知识,同时也能提高我们的阅读效率等. 想要做一个清晰 ...

  9. 《C#图解教程》读书笔记之四:类和继承

    本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.万物之宗:Object (1)除了特殊的Object类,其他所有类都是派生类,即使他们没有显示基类定义. ( ...

最新文章

  1. 【以太坊】搭建测试网络之ubuntu系统安装node.js
  2. js根据月数计算有效日期_你真的看懂产品生产日期了么
  3. gorm存指针数据_gormt: gormt 是一个数据库映射工具,可以将 mysql 数据库自动生成 golang sturct 结构...
  4. UI标签库专题六:JEECG智能开发平台 Autocomplete(自动补全标签 )
  5. Oracle Certified Master For Java EE 5/6 Comes
  6. 基于RGB图像的草莓叶片白粉病检测深度学习方法
  7. [postgresql]postgresql的锁介绍
  8. 使用单例时一定要注意的一个问题
  9. SQL SERVER 卸载清除步骤
  10. 美通企业日报 | 爱彼迎成为奥林匹克全球合作伙伴;腾讯理财通运营主体迁至腾富公司...
  11. 大批量数据导出到Excel
  12. 测试摇一摇次数的软件,iOS通过加速计计算摇一摇次数
  13. FileZilla Client ftp上传软件
  14. 【Python】爬虫爬取各大网站新闻(一)
  15. 全球与中国3D透视导航技术市场现状及未来发展趋势(2022)
  16. NO29、最小的K个数(应该记住大顶堆和小顶堆的区别与联系,并不难)
  17. 自学编程系列——3 面向对象编程
  18. R语言如何绘制变异系数曲线(24)
  19. 双网卡设置方法_无线和有线网络同时启用
  20. 股指期货和ETF的套利

热门文章

  1. 我用这 18 个神奇的库,美化了我的项目,真是亮瞎我的眼!
  2. 走出微服务误区:避免从单体到分布式单体
  3. 2021年的综艺节目:火了,但没完全火
  4. 颜色(color)透明
  5. LiveLink for MATLAB:COMSOL与MATLAB交互
  6. 速通JavaScript基础部分
  7. 千峰JAVA逆战班Day38
  8. 骗人的汇丰外汇系统,骗人的汇盈外汇系统。大家小心了。
  9. 算法与数据结构 - 排序详解
  10. html+css+vue面试