COM 学习小记录

  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)=0;
virtual ULONG _stdcall AddRef(void)=0;
virtual ULONG _stdcall Release(void)=0;
}

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

  QueryInterface是:IUnKnown的成员函数,客户可以通过此函数来查询组件是否支持某个特定的接口,返回一个指向组件支持的接口的指针,没有找到组件支持的接口则返回指针是NULL。

  进程内组件:进程内组件和客户程序运行在同一个进程地址空间中,所以一旦客户程序与组件程序建立起通信关系之后,客户程序得到的接口指针指向组件程序中接口的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 学习小记录

时间: 2024-10-17 03:30:28

COM 学习小记录的相关文章

java学习中,object 对象的使用(toString、equals、hashCode)(java 学习中的小记录)

java学习中,object 对象的使用(java 学习中的小记录)作者:王可利(Star·星星) object 对象(参考API学习) 重点掌握三个方法: 1.toString 返回该对象的字符串表示. 2.equals(object obj)指示其他某个对象是否与这个对象相等. 3.hashCode() 返回对象的哈希码. 详见代码的注释分析(一个是Person类重写方法,一个是Star类使用方法) Star类代码: 1 package study; 2 3 public class sta

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

利用JQ实现的,高仿 彩虹岛官网导航栏(学习HTML过程中的小记录)   作者:王可利(Star·星星) 总结: 今天学习的jQ类库的使用,代码重复的比较多需要完善.严格区分大小写,在 $("").css()   这里css是小写的,用 HBuilder 编写补全是大写的..这里要注意 主要使用的方法:jQuery 隐藏 / 显示    jQuery 淡出淡入 需要注意的知识点: 效果的样式: 代码如下:(亲们 自己展开拉~) 1 <!DOCTYPE html> 2 <

java学习中,成员内部类、匿名内部类(java 学习中的小记录)

java学习中,成员内部类.匿名内部类(java 学习中的小记录)作者:王可利(Star·星星) 内部类: 一个类中定义另外一个类,这样的类叫内部类. 内部类的文件名:外部类名$内部类名.class    内部类分两种: 1.成员内部类 如何访问成员内部类:             方式1:外部类中定义一个方法来创建内部类对象,再通过对象进行访问.             方式2:可以直接在其他类中直接创建内部类这个对象,通过对象访问.用点语.                       格式:

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

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

java学习中,异常和错误的简介、捕获异常、抛出异常、自定义异常(java 学习中的小记录)

java学习中,异常和错误的简介.捕获异常.抛出异常.自定义异常(java 学习中的小记录)作者:王可利(Star·星星) 异常:(API 的 java.lang 有一个异常,有很多很多) 在Java程序中也会程序出现不正常的情况,这个就叫异常.     Java是面向对象的语言,任何事物都可以用类来描述,同样的异常也是一种事物.Java中提供了很多的异常类.     多个异常堆积起来,就是一个异常体系.   Throwable:是异常类的父类,超类.Exception 异常.error错误.

java学习中,匿名函数、构造方法、构造代码块、构造方法中调用构造方法(java 学习中的小记录)

java学习中,匿名函数.构造方法.构造代码块.构造方法中调用构造方法(java 学习中的小记录) 作者:王可利(Star·星星) 匿名函数 匿名对象:没有名字的对象 匿名对象使用的注意点: 1.一般不会用匿名对象给属性赋值,无法获取属性值,每次new 都是一个新的对象. 2.匿名对象永远都不可能是一个对象. 如:person new().name = "星星":是不行的 匿名对象的好处:书写简单. 匿名对象使用的场景: 1.如果一个对象调用一个方法一次的时候,就可以用匿名对象来调用.

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

Java 打印金字塔 or 打印带数字的金字塔 (Java 学习中的小记录) 作者:王可利(Star·星星) 效果图: 代码如下: 1 class Star8 2 { 3 public static void main(String[] args) 4 { 5 /* 空格 6 * 1 2*i-1 3 4-1 4-i 7 *** 3 2 4-2 8 ***** 5 1 4-3 9 ******* 7 0 4-4 10 */ 11 //第一层循环控制的是行数 12 for(int i = 1;i<=

java学习中,面向对象的三大特性:封装、继承、多态 以及 super关键字和方法的重写(java 学习中的小记录)

java学习中,面向对象的三大特性:封装.继承.多态 以及 super关键字和方法的重写(java 学习中的小记录) 作者:王可利(Star·星星) 封装     权限修饰符:public 公共的,private 私有的     封装的步骤:          1.使用private 修饰需要封装的成员变量.          2.提供一个公开的方法设置或者访问私有的属性              设置 通过set方法,命名格式:     set属性名();  属性的首字母要大写 访问 通过ge

java学习中,接口的使用(重要,常用知识点)(java 学习中的小记录)

java学习中,接口的使用(重要,常用知识点)(java 学习中的小记录)作者:王可利(Star·星星) 接口(功能:用来添加拓展功能的) 例子:铅笔.带橡皮檫的铅笔. 两个功能:     1.写字......> 铅笔     2.擦字......> 橡皮擦 想法:定义一个铅笔类,定义一个橡皮擦类,定义一个带橡皮擦的铅笔类继承 铅笔类和橡皮擦类 但是java是单继承的.于是就有了解决的方法:接口(可以添加拓展功能) 如:一个铅笔类,给它添加一个接口给它一个拓展类(橡皮擦类) 接口的定义模式 用