COM 基础 之 三大基础接口
摘自 http://blog.csdn.net/liang4/article/details/7530512
1 COM组件实际上是一个C++类,而接口都是纯虚类。组件从接口派生而来。
2 COM组件有三个最基本的接口类,分别是IUnknown、IClassFactory、IDispatch。COM规范规定任何组件、任何接口都必须从IUnknown继承,IUnknown包含三个函数,分别是 QueryInterface、AddRef、Release
3 IClassFactory
IClassFactory的作用是创建COM组件。我们已经知道COM组件实际上就是一个类,那我们平常是怎么实例化一个类对象的?是用 ‘new’命令!很简单吧,COM组件也一样如此。但是谁来new它呢?不可能是客户程序,因为客户程序不可能知道组件的类名字,如果客户知道组件的类名字那组件的可重用性就要打个大大的折扣了,事实上客户程序只不过知道一个代表着组件的128位的数字串而已,这个等会再介绍。所以客户无法自己创建组件,而且考虑一下,如果组件是在远程的机器上,你还能new出一个对象吗?所以创建组件的责任交给了一个单独的对象,这个对象就是类厂。每个组件都必须有一个与之相关的类厂,这个类厂知道怎么样创建组件,当客户请求一个组件对象的实例时,实际上这个请求交给了类厂,由类厂创建组件实例,然后把实例指针交给客户程序。这个过程在跨进程及远程创建组件时特别有用,因为这时就不是一个简单的new操作就可以的了,它必须要经过调度,而这些复杂的操作都交给类厂对象去做了。IClassFactory最重要的一个函数就是CreateInstance,顾名思议就是创建组件实例,一般情况下我们不会直接调用它,API 函数都为我们封装好它了,只有某些特殊情况下才会由我们自己来调用它,这也是VC编写COM组件的好处,使我们有了更多的控制机会,而VB给我们这样的机会则是太少太少了。
4 IUnknown
COM规范规定任何组件、任何接口都必须从IUnknown继承,IUnknown包含三个函数,分别是 QueryInterface、AddRef、Release。这三个函数是无比重要的,而且它们的排列顺序也是不可改变的。 QueryInterface用于查询组件实现的其它接口,说白了也就是看看这个组件的父类中还有哪些接口类,AddRef用于增加引用计数, Release用于减少引用计数。引用计数也是COM中的一个非常重要的概念。大体上简单的说来可以这么理解,COM组件是个DLL,当客户程序要用它时就要把它装到内存里。另一方面,一个组件也不是只给你一个人用的,可能会有很多个程序同时都要用到它。但实际上DLL只装载了一次,即内存中只有一个 COM组件,那COM组件由谁来释放?由客户程序吗?不可能,因为如果你释放了组件,那别人怎么用,所以只能由COM组件自己来负责。所以出现了引用计数的概念,COM维持一个计数,记录当前有多少人在用它,每多一次调用计数就加一,少一个客户用它就减一,当最后一个客户释放它的时侯,COM知道已经没有人用它了,它的使用已经结束了,那它就把它自己给释放了。引用计数是COM编程里非常容易出错的一个地方,但所幸VC的各种各样的类库里已经基本上把 AddRef的调用给隐含了,在我的印象里,我编程的时侯还从来没有调用过AddRef,我们只需在适当的时侯调用Release。至少有两个时侯要记住调用Release,第一个是调用了 QueryInterface以后,第二个是调用了任何得到一个接口的指针的函数以后,记住多查MSDN 以确定某个函数内部是否调用了AddRef,如果是的话那调用Release的责任就要归你了。 IUnknown的这三个函数的实现非常规范但也非常烦琐,容易出错,所幸的事我们可能永远也不需要自己来实现它们。
5 IDispatch
IDispatch叫做调度接口。它的作用何在呢?这个世上除了C++还有很多别的语言,比如VB、 VJ、VBScript、JavaScript等等。可以这么说,如果这世上没有这么多乱七八糟的语言,那就不会有IDispatch。:-) 我们知道COM组件是C++类,是靠虚函数表来调用函数的,对于VC来说毫无问题,这本来就是针对C++而设计的,以前VB不行,现在VB也可以用指针了,也可以通过VTable来调用函数了,VJ也可以,但还是有些语言不行,那就是脚本语言,典型的如 VBScript、JavaScript。不行的原因在于它们并不支持指针,连指针都不能用还怎么用多态性啊,还怎么调这些虚函数啊。唉,没办法,也不能置这些脚本语言于不顾吧,现在网页上用的都是这些脚本语言,而分布式应用也是COM组件的一个主要市场,它不得不被这些脚本语言所调用,既然虚函数表的方式行不通,我们只能另寻他法了。时势造英雄,IDispatch应运而生。:-) 调度接口把每一个函数每一个属性都编上号,客户程序要调用这些函数属性的时侯就把这些编号传给IDispatch接口就行了,IDispatch再根据这些编号调用相应的函数,仅此而已。当然实际的过程远比这复杂,仅给一个编号就能让别人知道怎么调用一个函数那不是天方夜潭吗,你总得让别人知道你要调用的函数要带什么参数,参数类型什么以及返回什么东西吧,而要以一种统一的方式来处理这些问题是件很头疼的事。IDispatch接口的主要函数是 Invoke,客户程序都调用它,然后Invoke再调用相应的函数,如果看一看MS的类库里实现 Invoke的代码就会惊叹它实现的复杂了,因为你必须考虑各种参数类型的情况,所幸我们不需要自己来做这件事,而且可能永远也没这样的机会
COM 基础 之 三大基础接口的更多相关文章
- java基础语法(三大基础)
一.标识符 标识符是用于包名.类名.变量名.方法名.对象名.数组名.集合名等的命名: 规则: (1)可以使用英文字母.阿拉伯数字.下划线_.$符号 (2)不能以数字开头 (3)不能使用Java中的 ...
- Java14-java语法基础(十三)接口
Java14-java语法基础(十三)接口 一.接口 1.接口的作用 Java出于安全性.简化程序结构的考虑,不支持多继承而仅支持单继承.然而实际问题中很多情况下仅仅依靠单继承并不能将复杂的问题描述清 ...
- Java基础之抽象类与接口
Java基础之抽象类与接口 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候 ...
- 简易总结react-hook三大基础
react-hook的最重要的三大基础 import { useEffect, useState, useContext } from 'react' 1.每一个简单的一句话总结 useEffect ...
- VLAN 基础设置及Aceess接口
实验内容 本实验模拟企业网络场景.公司内网是一一个大的局域网,二层交换机S1放置在一楼,在一楼办公的部门有IT部和人事部;二层交换机S2放置在二楼,在二楼办公的部门有市场部和研发部.由于交换机组成的是 ...
- 朱晔的互联网架构实践心得S2E7:漫谈平台架构的工作(基础架构、基础服务、基础平台、基础中间件等等)
前言 程序开发毕竟还不是搬砖这种无脑体力劳动,需要事先有标准,有架构,有设计,绝对不是新公司今天创立,明天就可以开始编码的.其实很多公司在起步的时候没有财力和资源建设独立的基础架构或平台架构部门,甚至 ...
- MYSQL、PHP基础、面向对象基础简单复习总结
一.MYSQL 1.配置MySql 第一步安装服务器(apache). 第二部安装MySql界面程序 2 ...
- [.net 面向对象编程基础] (3) 基础中的基础——数据类型
[.net 面向对象编程基础] (3) 基础中的基础——数据类型 关于数据类型,这是基础中的基础. 基础..基础..基础.基本功必须要扎实. 首先,从使用电脑开始,再到编程,电脑要存储数据,就要按类型 ...
- [.net 面向对象编程基础] (19) LINQ基础
[.net 面向对象编程基础] (19) LINQ基础 上两节我们介绍了.net的数组.集合和泛型.我们说到,数组是从以前编程语言延伸过来的一种引用类型,采用事先定义长度分配存储区域的方式.而集合是 ...
随机推荐
- Go 修改字符串中的字符(中文乱码)
问题复现:修改字符串的第一个中文 先对原字符串做切片,然后进行拼接,得到新的字符串 func ModifyString(str string) string { tempStr := str[1:] ...
- 关于MQ的几件小事(四)如何保证消息不丢失
1.mq原则 数据不能多,也不能少,不能多是说消息不能重复消费,这个我们上一节已解决:不能少,就是说不能丢失数据.如果mq传递的是非常核心的消息,支撑核心的业务,那么这种场景是一定不能丢失数据的. 2 ...
- 普通选项卡+自动播放功能+向前/向后按钮 原生js
今天做了幻灯片,主要功能包括:普通选项卡,向前/向后播放按钮,向前?向后播放功能,自动播放功能 要实现简单选项卡功能是没有问题的,但是添加功能就出现各种各样的问题了 遇到的问题:1 下标问题 2普通选 ...
- 百度定位SDK 返回error code : 162 latitude : 4.9E-324 lontitude : 4.9E-324
Android应用使用百度定位SDK 返回error code : 162 latitude : 4.9E-324 lontitude : 4.9E-324 在使用百度定位SDK时遇到一个非常郁闷的问 ...
- m3u8系列(一)练手spider
本次目标 http://www.qiqi.la/vod-detail-id-46194.html 目的,down魔道祖师,实现 前期分析文件得到以下粗略步骤 1 进入二级页面,找到 <ifram ...
- MySQL操作规范总结
来源:静以致远√团团 用户权限管理创建用户命令:CREATE USER 'username'@'host' IDENTIFIED BY 'password';说明:Username所创建的用户名hos ...
- awk 内置函数的使用
转自:http://gdcsy.blog.163.com/blog/static/12734360920130241521280/ 一.split 初始化和类型强制 awk的内建函数sp ...
- rsync 应用总结
rysnc server端 1.vim /etcrsyncd.conf (用户rsync,目录,模块,非系统虚拟用户及密码文件) 2.创建共享目录 /data/www/{www,bbs,blog} 3 ...
- Seafile和Nextcloud相比较哪个好用
面对大量的照片视频,备份资料成了很多网友的刚需.但现在各大免费网盘,关闭地关闭,收费的收费,自建网盘成了一个不得已的选择.可以自建私有网盘的网盘程序最出名的要数Seafile和Nextcloud,一款 ...
- phpstudy修改端口及网站根目录和访问 localhost 显示目录文件夹
一.其它选项菜单=>phpStudy设置=>端口常规设置(勾选允许目录列表): 二. Apache http端口:80 网站目录:D:\phpStudy\PHPTutorial\WWW 默 ...