DirectX 采用了 COM 标准。而 DirectShow 是一套完全基于 COM 的应用系统。要想深入学习 DirectShow,掌握一些 COM 编程的基础知识是必不可少的。

一、COM 是什么

COM(Component Object Model,组件对象模型)是微软公司于 1993 年提出的一种组件技术,它是一种平台无关、语言中立、位置透明、支持网络的中间件技术。

在 COM 架构下,人们可以开发出各种各样功能专一的 COM 组件,然后将它们按照需要组合起来,构成复杂的应用系统。由此带来的好处是多方面的:可以将系统中的组件用新的替换掉,以便随时进行系统的升级和定制;可以在多个应用系统中重复利用同一个组件;可以方便的将应用系统扩展到网络环境下。

COM 与语言、平台无关的特性使所有的程序员均可充分发挥自己的才智与专长编写组件模块。组件实际上是一些小的二进制可执行程序,它们可以给应用程序,操作系统以及其他组件提供服务。开发自定义的 COM 组件就如同开发动态的,面向对象的 API。多个 COM 对象可以连接起来形成应用程序或组件系统,并且组件可以在运行时刻,在不被重新链接或编译应用程序的情况下被卸下或替换掉。Microsoft 的许多技术,如 ActiveX, DirectX 以及 OLE 等都是基于 COM 而建立起来的。并且 Microsoft 的开发人员也大量使用 COM 组件来定制他们的应用程序及操作系统。

COM 所含的概念并不止是在 Windows 操作系统下才有效。COM 并不是一个大的 API,它实际上象结构化编程及面向对象编程方法那样,也是一种编程方法。在任何一种操作系统中,开发人员均可以遵循 “COM方法”。

二、COM 组件

COM 本身只是一种规范,而不是实现。当使用 C++ 来实现时,COM 组件就是一个 C++ 类,而接口都是纯虚类。可以用如下的 C++ 代码来简单描述一个 COM 组件。

class Ifunction
{
public:
virtual Method1(...) = 0;
virtual Method2(...) = 0;
//...
}; class MyObject : public Ifunction
{
public:
virtual Method1(...){...}
virtual Method2(...){...}
//...
};

其中,Ifunction 就是我们常说的接口,而 MyObject 就是 COM 组件。COM 规范规定,任何组件或接口都必须从 IUnknown 接口中继承而来。

COM 组件有 3 种类型:进程内组件、本地进程组件和远程组件。Filter 一般是一种进程内组件,以 DLL(动态链接库)的形式提供服务。

三、COM 基本元素

(1)接口:一个名字以大写的I开头的抽象基类,包含一组虚方法,接口可以从其它接口继承,但不能继承于多个接口,只能从一个接口继承。

(2)coclass(Component Object Class,组件对象类,通常被称为 COM 类):COM 类通常就是一个 C++ 类,这个类继承自一个或者多个接口,并实现它们,COM 对象在内存中的表现就是这个 COM 类的一个实例。

(3)COM 库:操作系统的一部分,调用 COM 组件时就是 COM 库在协助你完成调用。

(4)COM 服务器:包含了一个或者多个 coclass 的二进制 DLLs 或者 EXE 执行体。

(5)注册:创建注册表入口的一个过程,告诉 Windows 操作系统 COM 服务器放在什么位置。

(6)取消注册:从注册表删除这些注册入口。

(7)GUID(全球唯一标示符 Globally unique identifier):是一个 128 位的数字,其实它和 COM 无关,在其他地方我们也经常看到它,只不过 COM 中的接口和 coclass 都拥有一个 GUID,因为是全球唯一的,所以避免了名称冲突。

(8)IID(接口ID):是 interface 的 GUID。

(9)CLSID(类 ID):是 coclass 的 GUID。

(10)HRESULT:是一个代表着成功或错误代码的整型或长整型的数字,对 COM 对象的调用经常会返回一个 HRESULT,虽然用H开头,但并不是句柄的意思。

四、COM 与 DirectShow

DirectShow 应用程序实际上是一种 COM 组件的客户程序,只是 COM 组件的 “使用” 问题。这些问题包括如何创建 COM 组件、如何得到组件对象上的接口以及调用接口方法、如何管理组件对象(即需要熟悉 COM 的引用计数机制)等。下面的代码是最一般的步骤。

CoInitialize(NULL);   // COM库初始化
// Do something
//...
IUnknown *pUnk = NULL;
IObject *pObject = NULL;
// 创建组件对象
HRESULT hr = CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown,(void**)&pUnk);
if (SUCCEEDED(hr))
{
// 查询得到组件对象上的接口
hr = pUnk->QueryInterface(IID_IObject, (voidI**)&pObject);
if (SUCCEEDED(hr))
{
// 调用接口的方法
pObject->SomeMethod();
pObject->Release();
}
pUnk->Release();
}
//...
CoUninitialize(); // 释放COM库使用的资源

对于 Filter 开发人员来说,需要掌握的 COM 知识就要多一点。因为 Filter 本身是一种 COM 组件,开发 Filter 涉及到了 COM 组件的 “实现” 问题。而这里只对 COM 做简单介绍,想要进一步了解可以搜索《COM技术内幕》一书。

参考:

【VS开发】COM组件技术概述

COM编程概述

《DirectShow开发指南》学习笔记_2

《DirectShow开发指南》1.3节 - COM 编程基础

COM 编程基础的更多相关文章

  1. 第二章 Matlab面向对象编程基础

    DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...

  2. [.net 面向对象编程基础] (1) 开篇

    [.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...

  3. Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式

    前言 啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~) 本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学 ...

  4. T-Sql编程基础

    T-sql编程 入门小游戏 T-sql编程基础,包括声明变量,if判断,while循环,以及使用一些基本函数. 记得在学校的时候,写过一个二人对打的文字输出游戏. 上代码 alter proc usp ...

  5. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  6. 如何夯实(Java)编程基础,并深入学习和提高

    如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...

  7. Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”

    Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...

  8. LINQ to XML 编程基础

    1.LINQ to XML类 以下的代码演示了如何使用LINQ to XML来快速创建一个xml: 隐藏行号 复制代码 ?创建 XML public static void CreateDocumen ...

  9. [.net 面向对象编程基础] (2) 关于面向对象编程

    [.net 面向对象编程基础]  (2)  关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问 ...

  10. [.net 面向对象编程基础] (3) 基础中的基础——数据类型

    [.net 面向对象编程基础] (3) 基础中的基础——数据类型 关于数据类型,这是基础中的基础. 基础..基础..基础.基本功必须要扎实. 首先,从使用电脑开始,再到编程,电脑要存储数据,就要按类型 ...

随机推荐

  1. 《收获,不止SQL优化》这本书,有很多即用的脚本工具,或者根据自己的需求,改造重用,可以积累到自己的工具库中。

    以下两个脚本,官方来源: https://github.com/liangjingbin99/shouhuo/tree/master/%E7%AC%AC05%E7%AB%A0 1. 找出未使用绑定变量 ...

  2. s3c2440裸机-内存控制器(四、SDRAM原理-cpu是如何访问sdram的)

    1.SDRAM原理 black (1)SDRAM内部存储结构: (2)再看看与2440连接的SDRAM原理图: sdram引脚说明: A0-A12:地址总线 D0-D15:数据总线(位宽16,2片级联 ...

  3. 给定数轴上的n个点,求距离最近的两个点的距离

    public class MinimumSpacing { //给定平面上的n个点,求距离最近的两个点的距离. //无从下手的话,先分解问题,分解成简单的,逐个分析,然后再合在一起考虑 //这是个2维 ...

  4. 集合系列 Set(八):TreeSet

    TreeSet 是 Set 集合的红黑树实现,但其内部并没有具体的逻辑,而是直接使用 TreeMap 对象实现.我们先来看看 TreeSet 的定义. public class TreeSet< ...

  5. Java连载58-静态内部类、成员内部类详解

    一.内部类的分类: (1)静态内部类(2)成员内部类(3)局部内部类(4)匿名内部类 二.静态内部类 1.静态内部类可以等同的看做是静态变量 内部类的重要作用:可以访问外部类中的私有数据 2.静态内部 ...

  6. CSS画一个三角形,CSS绘制空心三角形,CSS实现箭头

     壹 ❀ 引 这两天因为项目工作较少,闲下来去看了GitHub上关于面试题日更收录的文章,毕竟明年有新的打算.在CSS收录中有一题是 用css创建一个三角形,并简述原理 .当然对于我来说画一个三角形是 ...

  7. jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解

    本节说一下DOM操作模块里的包裹元素子模块,该模块可将当前匹配的元素替换指定的DOM元素,有如下方法: wrap(html)               ;在每个匹配元素的外层添加一层DOM元素   ...

  8. Linux系统:centos7下搭建Nginx和FastDFS文件管理中间件

    本文源码:GitHub·点这里 || GitEE·点这里 一.FastDFS简介 1.基础概念 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件上传 ...

  9. 计算机网络知识(TCP连接,TCP/UDP区别,HTTP与HTTPS,Socket原理等等)

    1.网络七层协议包含,物理层.数据链路层.网络层(ip协议).传输层(TCP传输控制协议.UDP用户数据报协议).会话层.表示层.应用层(http协议).是一个提供的概念架构协议. 2.TCP/IP协 ...

  10. 解析innodb中的MVCC

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...