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. Auto入门 之 常用概念

    1.SEMI (Semiconductor Equipment And Materials International)  国际半导体设备与材料产业协会 2.SECS SECS协议是基于RS-232或 ...

  2. Java学习笔记-Java文件操作流

     day03 输入输出流:读入写出  节点流:   有明确的来源和去向   往往对字节操作 节点流又叫低级流.字节流   处理流:  没有明确的来源和去向  往往对低级流或其他高级流进行操作,不能独立 ...

  3. 「漏洞预警」Apache Flink 任意 Jar 包上传导致远程代码执行漏洞复现

    漏洞描述 Apache Flink是一个用于分布式流和批处理数据的开放源码平台.Flink的核心是一个流数据流引擎,它为数据流上的分布式计算提供数据分发.通信和容错功能.Flink在流引擎之上构建批处 ...

  4. C语言基本数据类型的转换

    变量的数据类型是可以转换的.转换的方法有两种,一种是自动转换,一种是强制转换.自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成.自动转换遵循以下规则:1) 若参与运算量的类型不同,则先转换 ...

  5. Java面试准备基础篇_11.24

    Java类加载机制 Java内存模型JMM 为什么 Redis 单线程能支撑高并发? 高并发下的接口幂等性解决方案! 面试官问:平常你是怎么对 Java 服务进行调优的? JAVA虚拟机(JVM)六: ...

  6. RTP通用头部扩展

    概览 本文为阅读RFC5285时对RTP头部扩展的记录笔记,介绍了one-byte-header和two-byte-header情况下的rtp头部扩展 rtp头部扩充 在RFC3550中, 一个通用的 ...

  7. 【Postman】举例实战——天气查询

    准备工作: 1.下载postman(搜索官网下载即可) 2.接口文档(以聚合上去免费API:天气查询接口) 打开postman: 1.输入url 2.请求方式 3.请求参数 4.在postman中运行 ...

  8. import com.sun.org.apache.xml.internal.security.utils.Base64问题

    ———————————————— 版权声明:本文为CSDN博主「荚小白」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csd ...

  9. dom元素的tabindex属性介绍及在vue项目中的应用

    dom元素的tabindex属性介绍及在vue项目中的应用 tabindex属性作用 让普通dom元素变为可聚焦的元素 让普通dom元素可以参与顺序键盘导航(通常使用Tab键,因此得名). tabin ...

  10. [python / selenium] - 用python刷公选课是一种什么体验?

    前言 看公选课还是能学到很多知识的,这里是给大家提供一个selenium的使用思路(好好学公选课,我真的看了) 思路 当观看者移动鼠标到某一范围时就会停止播放,就让selenium一直将鼠标悬停在视频 ...