COM 编程基础
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技术内幕》一书。
参考:
《DirectShow开发指南》1.3节 - COM 编程基础
COM 编程基础的更多相关文章
- 第二章 Matlab面向对象编程基础
DeepLab是一款基于Matlab面向对象编程的深度学习工具箱,所以了解Matlab面向对象编程的特点是必要的.笔者在做Matlab面向对象编程的时候发现无论是互联网上还是书店里卖的各式Matlab ...
- [.net 面向对象编程基础] (1) 开篇
[.net 面向对象编程基础] (1)开篇 使用.net进行面向对象编程也有好长一段时间了,整天都忙于赶项目,完成项目任务之中.最近偶有闲暇,看了项目组中的同学写的代码,感慨颇深.感觉除了定义个类,就 ...
- Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式
前言 啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~) 本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学 ...
- T-Sql编程基础
T-sql编程 入门小游戏 T-sql编程基础,包括声明变量,if判断,while循环,以及使用一些基本函数. 记得在学校的时候,写过一个二人对打的文字输出游戏. 上代码 alter proc usp ...
- [Java入门笔记] 面向对象编程基础(二):方法详解
什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...
- 如何夯实(Java)编程基础,并深入学习和提高
如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...
- Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”
Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...
- LINQ to XML 编程基础
1.LINQ to XML类 以下的代码演示了如何使用LINQ to XML来快速创建一个xml: 隐藏行号 复制代码 ?创建 XML public static void CreateDocumen ...
- [.net 面向对象编程基础] (2) 关于面向对象编程
[.net 面向对象编程基础] (2) 关于面向对象编程 首先是,面向对象编程英文 Object-Oriented Programming 简称 OOP 通俗来说,就是 针对对象编程的意思 那么问 ...
- [.net 面向对象编程基础] (3) 基础中的基础——数据类型
[.net 面向对象编程基础] (3) 基础中的基础——数据类型 关于数据类型,这是基础中的基础. 基础..基础..基础.基本功必须要扎实. 首先,从使用电脑开始,再到编程,电脑要存储数据,就要按类型 ...
随机推荐
- [20191125]探究等待事件的本源.txt
[20191125]探究等待事件的本源.txt --//当工作中遇到oracle的性能问题时,查看awr报表提供很好的解决问题途径.但是有时候很容易想当然.--//比如以前我一看到 log file ...
- tomcat启停脚本
脚本存放目录 /etc/init.d/ #!/bin/bash # description: Tomcat8 Start Stop Restart # processname: tomcat8 # c ...
- Red Hat Enterprise Linux 官方正式版镜像下载
Red Hat Enterprise Linux是美国红帽公司开发的商业市场导向的Linux发行版,为方便大家学习研究,整理分享历代红帽官方正式版镜像给有需要的朋友们. 下载地址:https://ww ...
- 开发一个这样的 APP 要多长时间?
作者:蒋国刚 www.cnblogs.com/guogangj/p/4676836.html 这是一个“如有雷同,纯属巧合”的故事,外加一些废话,大家请勿对号入座.开始了…… 我有些尴尬地拿着水杯,正 ...
- go语言之map
go语言的map就相当于python的dict 1.map的初始化 //创建map //k的类型是int,v的类型是string var test25_1 map[int]string fmt.Pri ...
- go语言之if语句和switch语句和循环语句
1.if语句 package main import ( "fmt" "io/ioutil" ) func main() { //流程控制 //使用常量定义一个 ...
- Vue 从入门到进阶之路(十二)
之前的文章我们介绍了一下 vue 中插槽的使用,本章我们接着介绍一下 vue 中的作用域插槽. <!DOCTYPE html> <html lang="en"&g ...
- 【解决】MySQL提示启动成功,实际进程并没有起来
一.概括: 1.查看运行日志 vim /var/log/mariadb/mariadb.log 2.修改配置文件 vim /etc/my.cnf 3.修改文件权限 chown mysql.mysql ...
- 通过idea将maven工程转为web项目
前言 吐槽一下网上的各种转换教程..说的真的是吵来吵去,有用的东西极少.特此自己写一篇好使的. 转换过程 建好的maven工程 建好的maven工程长这个鬼样子~~,没有使用骨架.就是普通的建立方式. ...
- C#二位数组 数组矩阵对角线之和
二维数组: public static void Main(string[] args) { int[,] a = new int[3, 3]; Random rom = new Random(); ...