文章目录

  • COM 简介
  • 概念
  • CoCreateInstance
  • IUnKnown 接口
  • IUnknown 的工作原理
    • 引用计数
    • 接口查询

COM 简介

Microsoft 组件对象模型 (COM) 是一个独立于平台的分布式面向对象的系统,用于创建可交互的二进制软件组件。 COM 是 Microsoft 的 OLE (复合文档) 、ActiveX (Internet 组件) 等的基础技术。
若要了解 COM (所有基于 COM 的技术) ,必须了解它不是面向对象的语言,而是一种标准。 用于创建在运行时进行交互的可重用的软件库。 无需将其编译到应用程序中,即可使用 COM 库。 COM 是许多 Microsoft 产品和技术的基础,例如 Windows Media Player 和 Windows 服务器。

COM 定义适用于许多操作系统和硬件平台的二进制标准。 对于网络计算,COM 定义了标准线路格式和协议,以便在不同硬件平台上运行的对象之间进行交互。 COM 与实现语言无关,这意味着你可以使用不同的编程语言(如 c + + 和 .NET Framework 中的编程语言)来创建 COM 库。

COM 规范提供启用跨平台软件重用的所有基本概念:

  • 组件间函数调用的二进制标准。
  • 将函数强类型化分组到接口中的设置。
  • 提供多态性、功能发现和对象生存期跟踪的基接口。
  • 唯一标识组件及其接口的机制。
  • 从部署创建组件实例的组件加载程序。

COM 具有多个共同工作的部分,可让你创建从可重用组件生成的应用程序:

  • 提供符合 COM 规范的运行时环境的 主机系统 。
  • 定义功能协定和实现接口的 组件 的 接口。
  • 向系统提供组件的 服务器,以及使用组件提供的功能的 客户端。
  • 跟踪将组件部署在本地和远程主机上的位置的 注册表 。
  • 一种 服务控制管理器 ,用于查找本地和远程主机上的组件,并将服务器连接到客户端。
  • 一种 结构化存储 协议,用于定义如何在主机的文件系统上导航文件的内容。
    跨主机和平台启用代码重用是 COM 的核心。 可重复使用的接口实现称为 " 组件"、" 组件对象" 或 " COM 对象"。 组件实现一个或多个 COM 接口。

通过设计库实现的接口来定义自定义 COM 库。 库的使用者可以发现和使用其功能,而无需了解库的部署和实现细节。

概念

接口:成员函数的集合,面向对象中接口类。
IID:每个接口都有其自己的唯一接口标识符 IID, IID 是全局唯一标识符 (GUID) , IID只会对应一个接口

COM类: COM类可以创建实现了多个 接口(接口类)
CLSID:每个com 类都有一个CLSID,在windows 上com 类 的实现在 dll 或者 exe 上。

映射关系:COM 维护系统上安装的 COM 对象的所有 Clsid 的注册数据库。 注册数据库是每个 CLSID 之间的映射,以及承载相应类的 DLL 或 EXE 的位置。 每当调用方想要创建 COM 类的实例时,COM 都将查询此数据库。 调用方只需了解用于请求类的新实例的 CLSID。

客户端/服务器:COM 对象及其调用方之间的交互建模为客户端/服务器关系。 客户端是向系统请求 COM 对象的调用方,服务器是包含向客户端提供服务的 COM 对象的模块。

CoCreateInstance

com 框架提供的接口,用于获取想要的对象指针
COM 客户端是向系统传递 CLSID 以请求 COM 对象实例的任何调用方。 创建实例的最简单方法就是调用 COM 函数 CoCreateInstance。

这是一段dshow 创建graph 的代码

 ComPtr<IGraphBuilder> graph;HRESULT hr;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IFilterGraph, (void **)&graph);

看一下

HRESULT _stdcall  CoCreateInstance(REFCLSID rclsid,LPUNKNOWN pUnkOuter,DWORD dwClsContext,REFIID riid,LPVOID * ppv);

第一个参数:待创建组件的CLSID。 用于找到对应COM 类,和所在的DLL 或者 exe。

第二个参数:用于聚合组件。

第三个参数:dwClsContext的作用是限定所创建的组件的执行上下文。

第四个参数:iid为组件上待使用的接口的iid。也就是 接口类对应的IID

CoCreateInstance 将在最后一个参数中返回此接口的指针。通过将一个IID传给CoCreateInstance,客户将无需在创建组件之后去调用 其QueryInterface函数。

HRESULT CoCreateInstance(const CLSID& clsid,IUnknown* punkonwnDuter,DWORD dwClsContext,const IID& iid,void** ppv)
{// Set the out paameter to NULL*ppv = NULL;// 首先根据clsid获得COM类的工厂类IClassFactory* pIFactory = NULL;HRESULT hr = CoGetClassObject(clsid,dwClsContext,NULL,IID_IClassFactory,(void**)&pIFactory);if (SUCCEEDED(hr)){// 使用工厂类,传入接口 IID, 来创建接口对象hr = pIFactory->CreateInstance(punkonwnDuter, iid, ppv);pIFactory->Release()();}return hr;
}

IUnKnown 接口

IUnknown是指COM标准接口。所有COM接口都继承IUnKnown。
他负责两项工作:

  • IUnknown::QueryInterface负责得到该组件的其他接口的指针
  • IUnknown::AddRef/Release负责管理该组件的生存期,但有人使用该组件时,保证该组件不会被意外删除;再没人使用该组件时,保证该组件被自动删除

IUnknown 的工作原理

IUnknown 中的方法使应用程序能够查询组件上的接口并管理组件的引用计数。

引用计数

引用计数是一个内部变量,在 AddRef 方法中递增,并在 Release 方法中减少。 基类管理引用计数,并同步对多个线程中的引用计数的访问。

接口查询

查询接口也很简单。 调用方传递两个参数:接口标识符 (IID) ,以及指针的地址。 如果组件支持请求的接口,它会将指针设置为接口,并递增其自己的引用计数,并返回 S _ OK。 否则,它会将指针设置为 NULL ,并返回 E _ NOINTERFACE。 以下伪代码显示了 QueryInterface 方法的一般轮廓。 下一节中描述的组件聚合带来了一些额外的复杂性。

第一点:说简单一点就是,dynamic_cast。查询 CoCreateInstance 创建出来的对象,是否可以转换成底层接口,其实就是c++ 中 dynamic_cast,同时增加一个引用计数而已。如果是纯c++ 的情况,应该就不需要这个接口了。

第二点:也是工厂模式,根据riid 创建 对象

STDMETHODIMP CapturePin::QueryInterface(REFIID riid, void **ppv)
{if (riid == IID_IUnknown) {AddRef();*ppv = this;} else if (riid == IID_IPin) {AddRef();*ppv = (IPin *)this;} else if (riid == IID_IMemInputPin) {AddRef();*ppv = (IMemInputPin *)this;} else {*ppv = nullptr;return E_NOINTERFACE;}return NOERROR;
}

windows - COM 组件介绍相关推荐

  1. C:\WINDOWS\WinSxS目录介绍,来自百度词条

    C:\WINDOWS\WinSxS目录介绍,来自百度词条 来源:重庆沙坪坝区网吧联盟    发表时间:2010-08-16 03:22    查看:9次     WinSxS是Windows目录下一个 ...

  2. android的应用组件,跟我学android-Android应用基本组件介绍(五)

    Activity activity 是最基本的模块,我们成为活动,一个activity通常就是一个单独的屏幕,每一个活动都被实现为一个独立的类,且都继承活动的基类.在activity的实现类里显示用户 ...

  3. RDIFramework.NET ━ .NET快速信息化系统开发框架 ━ 工作流程组件介绍

    RDIFramework.NET ━ .NET快速信息化系统开发框架 工作流程组件介绍 RDIFramework.net,基于.NET的快速信息化系统开发.整合框架,给用户和开发者最佳的.Net框架部 ...

  4. 最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)

    在项目开发中,除了对数据的展示更多的就是对文件的相关操作,例如文件的创建和删除,以及文件的压缩和解压.文件压缩的好处有很多,主要就是在文件传输的方面,文件压缩的好处就不需要赘述,因为无论是开发者,还是 ...

  5. 修复win10的更新服务器,Win10系统无法更新如何修复Windows Update组件

    我们在使用win10系统的时候,经常需要进行一些更新,可以给用户们带来更多的安全和更好的操作体验,但是有时候可能会遇到无法更新的情况,那么可能是Windows Update组件受损,要如何进行修复呢? ...

  6. 高效而稳定的企业级.NET Office 组件Spire(.NET组件介绍之二)

    在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是"这个系统似乎就是专门操作文档的".毕竟现在的很多办公中大都是在PC端操作文档等软件,在这些庞 ...

  7. Windows窗口消息介绍

    Windows窗口消息介绍 // #include "AFXPRIV.H"//消息值的定义来源 #include "Dde.h"//DDE消息值的定义来源 #i ...

  8. 云计算职业技能大赛组件介绍(一)

    云计算职业技能大赛组件介绍(一) 上文我们准备好了一个实验平台,我们了解了该如何搭建开源平台open stack,在此基础上,我们该理论的,系统的,详细的了解一下open stack的各个组件的作用和 ...

  9. RDIFramework.NET敏捷开发框架 ━ 工作流程组件介绍

    RDIFramework.NET,基于全新.NET Framework与.NET Core的快速信息化系统敏捷开发.整合框架,给用户和开发者最佳的.Net框架部署方案.为企业快速构建垮平台.企业级的应 ...

最新文章

  1. F5负载均衡会话保持技术及原理技术白皮书
  2. Cocos2d之Texture2D类详解之将文件加载成Texture2D对象
  3. 城市大脑不仅是AI系统,更是结合人类智慧的混合智能巨系统
  4. 我的新浪微博,顺便总结下近况
  5. UITextView实现PlaceHolder的方式
  6. 协调器太多,cc2530的终端或则路由器选择性加入协调器的方法
  7. Java基础总结(一)
  8. python 高阶函数一 概念
  9. 从崩溃的选课系统,论为什么更安全的 HTTPS 协议没有被全面采用
  10. 毕业三五年,怎么拿到百万年薪?
  11. GNS3 使用错误 ( Dynamips error when running command 'nio create_udp )
  12. matlab 正版下载,matlab软件正版
  13. 用Python写几个小游戏(附源码)
  14. oracle translate using,oracle translate() 详解
  15. DNC: A deep neural network-based clustering-oriented network embedding algorithm 2021
  16. C++多态的职工管理系统
  17. Excel2010 count,countif,countifs使用
  18. Python学习手册之控制结构(二)
  19. 天融信虚拟企业防火墙学习
  20. OJ刷题记录:将十进制数转换成八进制数 题目编号:545

热门文章

  1. 全志allwinner A40i平台ads1115模块AD采样
  2. 基于对象分割的DEM 数据编辑
  3. STM32F103C6 IO中断之protues仿真
  4. Ubuntu20/视觉SLAM十四讲踩坑记录
  5. Diverse Embedding Expansion Network and Low-Light Cross-Modality Benchmark for V-I Re-ID:如何有效利用生成嵌入?
  6. L 版 -360stack安全大学部署文档
  7. Flutter json 和 对象之间的转换
  8. 巴菲特一生最经典的演讲
  9. 电商项目实战测试流程
  10. 操作系统课程设计报告总结(下)