COM组件程序:模块,它可以是 动态连接库(DLL) && 可执行程序(EXE),称为 进程内组件(in-of-process component) && 进程外组件(out-of-process component)。

  COM对象:建立在二进制可执行代码级的基础上,因此COM对象是语言无关的,这一特性使得使用不同编程语言开发的组件对象进行交互成为可能。

  COM标准:规范 && 实现。规范:定义了组件和组件之间的通信机制,不依赖于特定的语言和操作系统;实现:COM库,COM库为COM规范的具体实现提供了一些核心服务。实现包括一些核心的系统级代码,这部分核心代码使得对象和客户之间可通过接口在二进制代码级进行交互 。

  标志对象:每个对象用一个128位GUID来标识,称为CLSID(class identifier,类标识符或类ID),用CLSID标识对象可以保证(概率意义上)在全球范围内的唯一性。只要系统中含有这类COM对象的信息 && 包括COM对象所在的模块文件(DLL或EXE文件) && COM对象在代码中的入口点,客户程序就可以由此CLSID来创建COM对象。

  标志接口:COM模型中,对象本身对客户来说是不可见,客户只能通过接口请求服务。每一个接口都由一个128位的全局唯一标识符(GUID,Globally Unique Identifier)来标识,客户通过GUID获得接口的指针,通过接口指针调用相应的成员函数。

  使用服务:客户成功创建对象后,它得到一个指向对象某个接口的指针,因为COM对象至少实现一个接口,所以客户就可以调用该接口提供的所有服务。

  COM库:一般不在应用程序层实现,而在操作系统层次上实现,因此一个操作系统只有一个COM库实现,而且COM库的实现必须依赖于具体的系统平台,尤其是系统底层的一些标准。库可以保证所有的组件按照统一的方式进行交互操作,使我们在编写COM应用时,可以不编写为进行COM通信而必需的大量基础代码,而直接利用COM库提供的API进行编程,加快了开发速度。

  COM对象特性:封装性 && 重用性 && 多态性。但这种多态性需要通过COM对象所具有的接口才能体现出来,就像C++对象的多态性需要通过其(virtual)函数才能体现一样。

  COM接口规范:接口是包含了一组函数的数据结构,这组成员函数是组件对象暴露出来的所有信息,通过这组数据结构,客户代码可以调用组件对象的功能。客户程序用一个指向接口数据机构的指针来调用接口成员函数。接口指针实际上又指向另一个指针,这第二个指针指向一组函数,称为接口函数表(虚函数表),接口函数表中的每一项为4个字节长的函数指针,这与对象的具体实现连接起来,客户只要获得了接口指针,就可以调用到对象的实际功能。对于一个接口来说,他的虚函数表vtable是确定的,因此接口的成员函数个数是不变的,而且成员函数的先后顺序也是不变的;对于每个成员函数来说,其参数和返回值也是确定的。

  接口描述语言:如何描述接口呢?COM接口描述语言是IDL,IDL接口描述语言不仅可用于定义COM接口,同时还定义了一些常用的数据类型,也可以描述自定义的数据结构。对于接口成员函数,我们可以指定每个参数的类型,输入输出特性,甚至支持可变长度的数组的描述。IDL支持指针类型,与C/C++很类似。Microsoft Visual C++提供了MIDL工具,可以把IDL接口描述文件编译成C/C++兼容的接口描述头文件(.h),从而可以把一种奇怪的东东IDL描述的接口转化C++形式:

IUnknown的定义(IDL):

interface IUnknown
{ HRESULT QueryInterface([in] REFIID iid, [out] void **ppv);
ULONG AddRef(void);
ULONG Release(void);
} IUnknown的定义(C++): class IUnknown
{ Public:
virtual HRESULT _stdcall QueryInterface([in] REFIID iid, [out] void **ppv)=;
virtual ULONG _stdcall AddRef(void)=;
virtual ULONG _stdcall Release(void)=;
}

  IUnKnown是:一个接口,所有COM接口都继承IUnKnown。定义在WIN32 SDK中的UNKNWN头文件中。

  QueryInterface是:IUnKnown的成员函数,客户可以通过此函数来查询组件是否支持某个特定的接口,返回一个指向组件支持的接口的指针,没有找到则返回NULL。用QueryInterface将组件抽象成由多个相互独立的接口构成的集合。

  组件的生命期:这一点是通过对接口的引用计数实现的。客户并不能直接控制组件的生命期,当使用完一个接口而要用组件的另一个接口时,是不能将该组件释放的,对组件的释放可以由组件在客户使用完所有组件之后自己完成。AddRef和Release实现的是一种名为引用计数的内存管理技术,当客户从组件获得一个接口时,此引用数值将增加;当使用完某个接口时,组件的引用计数值将减1;当引用计数值为0时组件可以将自己从内存中删除。AddRef和Release可以增加和减少这一计数值。

  进程内组件:进程内组件和客户程序运行在同一个进程地址空间中,所以一旦客户程序与组件程序建立起通信关系之后,客户程序得到的接口指针指向组件程序中接口的vtable,这vtable包含了所有成员函数地址,客户代码可以直接调用这些成员函数,所以效率非常高。DLL程序是在运行时刻被客户装入到内存中的,所以DLL模块本身也是独立的,它并不依赖于客户程序。

  操作DLL程序:有三个系统函数,LoadLibrary && GetProcAddress && FreeLibrary。一般地,对于DLL程序的使用过程按照这样的步骤进行:

首先,客户程序使用LoadLibrary函数装入DLL,该函数返回模块的实例句柄,供以后操作该模块使用。

然后,客户程序可以调用GetProcAddress函数获得DLL中引出的函数的地址,我们既可以按函数的序号(在DEF文件中指定)也可以按函数的名字来获取引出函数的地址,因为客户程序和DLL程序在相同的内存地址空间中,所以客户程序可以直接调用这些引出函数。

最后,FreeLibrary,把DLL程序卸出内存,以便释放资源。

  COM组件不是:COM组件不是DLL,COM只是利用DLL来给组件提供动态链接的能力;COM组件不是一个API函数集;COM组件不是类。

  创建COM对象:客户程序通过调用CoCreateInstance来创建对象的一个实例,并向想要创建的对象传送一个CLSID。

   DLL:是一种程序动态调用以及连接的技术,他和组件是完全两种不同的概念,很多组件都采用这种技术作为自身的连接方式。

  IDispatch:IDispatch的存在是因为有些语言不支持虚函数表vtable,比如vb,asp等,它的主要作用是”接收一个函数的名称并执行它“,IDispatch有几个函数:

GetIDsOfNames:取一个函数的名称并返回其调度ID,或称DISPID
Invoke:可以将DISPID作为函数数组指针的索引

附:

http://blog.csdn.net/l12345678/article/details/1707629

COM 学习小记录的更多相关文章

  1. C++ VARIANT 学习小记录

    一:为什么会有这个? 目前,计算机语言有很多(大哥,为什么不能就那么一样呢?),如C++.Java,此外还有JavaScript.VBScript等脚本语言,它们自立门派,各自维护自己的数据类型. C ...

  2. Java 打印金字塔 or 打印带数字的金字塔 (Java 学习中的小记录)

    Java 打印金字塔 or 打印带数字的金字塔 (Java 学习中的小记录) 作者:王可利(Star·星星) 效果图: 代码如下: class Star8 { public static void m ...

  3. Java 需要记得、了解的关键词 (Java 学习中的小记录)

    Java 需要记得.了解的关键词 (Java 学习中的小记录)     作者:王可利(Star·星星) 总结:本次随笔,仅且拿来平时翻阅记忆用

  4. 关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)

    关于HTML中,绝对定位,相对定位的理解...(学习HTML过程中的小记录)   作者:王可利(Star·星星) HTML中 相对定位:position:relative; 绝对定位:position ...

  5. 利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)

    利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)   作者:王可利(Star·星星) 总结: 今天学习的jQ类库的使用,代码重复的比较多需要完善.严格区分大小写,在 $(" ...

  6. html/css 盒子布局 Margin 、Padding 、border 以及 清除浮动的知识 (学习HTML过程中的小记录)

    html/css  盒子布局 Margin .Padding .border 以及 清除浮动的知识 (学习HTML过程中的小记录) 作者:王可利(Star·星星) width     是"宽 ...

  7. Android学习小Demo(19)利用Loader来实时接收短信

    之前写过一篇文章<Android学习小Demo(13)Android中关于ContentObserver的使用>,在里面利用ContentOberver去监測短信URI内容的变化.我们先来 ...

  8. 跟我一起,利用bitcms内容管理系统从0到1学习小程序开发:一、IIS下SSL环境搭建

    缘起 1.从事互联网十来年了,一直想把自己的从事开发过程遇到的问题给写出来,分享给大家.可是可是这只是个种想法,想想之后就放下了,写出来的类文章是少之又少.古人说无志之人常立志,有志之人立长志.今天, ...

  9. Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

随机推荐

  1. tomcat配置虚拟主机

    在眼下,非常多server都是一台server对外能够訪问非常多个javaEE的项目,这样的实现方式就须要在tomcat里面配置虚拟主机了!以下就说说怎样配置虚拟主机: 找到tomcat的安装文件夹, ...

  2. 通过缓存数据库结果提高PHP性能(转)

    众所周知,缓存数据库查询的结果可以显著缩短脚本执行时间,并最大限度地减少数据库服务器上的负载.如果要处理的数据基本上是静态的,则该技术将非常有效.这是因为对远程数据库的许多数据请求最终可以从本地缓存得 ...

  3. redo log write和flush

    http://bbs.chinaunix.net/thread-1753130-1-1.html 在事务提交时innobase会调用ha_innodb.cc 中的innobase_commit,而in ...

  4. placement new 操作符

    placement new操作符能够在分配内存时指定内存位置.下面的程序使用了placement new操作符和常规new操作符给对象分配内存. // placenew.cpp -- new, pla ...

  5. IntellijIdea中常用的快捷键

    快速查找类:Ctrl+N 提示:Ctrl+Space 提示:Ctrl+Shift+Space 查看documentation:Ctrl+Q 查找类.方法.变量的引用:Alt+F7 定位类.方法.变量的 ...

  6. Gradle Goodness: Set Java Compiler Encoding--转载

    原文地址:http://java.dzone.com/articles/gradle-goodness-set-java If we want to set an explicit encoding ...

  7. 使用OPC的方式去连接PLC进行AB SLC-5_04数据的采集

    1.  必备软件 Rslinx classic 2.57 .net framework 2.0 VS2013 OS: win7 enterprise x64 2.  软件安装 2.1.安装RSlinx ...

  8. ArcGIS: version not specified. You must call RuntimeManager.Bind before creat

    打开program.cs把ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop);这句放到Applicatio ...

  9. asp.net session容易丢失解决方案

    web Form 网页是基于HTTP的,它们没有状态, 这意味着它们不知道所有的请求是否来自 同一台客户端计算机,网页是受到了破坏,以及是否得到了刷新,这样就可能造成信息的 丢失. 于是, 状态管理就 ...

  10. iOS下使用sqlite3

    1.创建数据库 使用firefox的sqlite manager创建和打开数据库,详细请参考: http://www.cnblogs.com/hanjun/archive/2012/10/29/274 ...