COM学习笔记<1>

   杨老师的个人专栏地址:http://www.vckbase.com/vckbase/columnist/yangfeng/,敝人在此极力推荐,想学COM的朋友们千万别错过了这绝好的入门资料哦~

1,GUID,UUID,CLSID,IID,REFCLSID:

typedef struct _GUID {
    DWORD Data1;    
// 随机数
    WORD Data2;    // 和时间相关
    WORD Data3;    // 和时间相关
    BYTE Data4[8];    // 和网卡MAC相关
} GUID;

typedef GUID CLSID;  
// 组件ID
typedef GUID IID;    // 接口ID
#define REFCLSID const CLSID &

// 常见的声明和赋值方法
CLSID CLSID_Excel = {0x00024500,0x0000,0x0000,{0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
struct __declspec(uuid("00024500-0000-0000-C000-000000000046")) CLSID_Excel;
class DECLSPEC_UUID("00024500-0000-0000-C000-000000000046") CLSID_Excel;
// 注册表中的表示方法
{00024500-0000-0000-C000-000000000046}

 

  如果使用开发环境编写组件程序,则IDE会自动帮你产生CLSID.可以手动写CLSID,但难以保证与其它CLSID不重复,在程序中可以使用CoCreateGuid来产生GUID,或者通过工具来产生.

  ProgId(Program ID)&CLSID其实是一个概念的两种不同的表现形式.注册表子键 ProgID 和 VersionIndependentProgID 分别表示真正的 ProgID 和版本无关的 ProgID.

函数 功能说明
CLSIDFromProgID()、CLSIDFromProgIDEx() 由 ProgID 得到 CLSID。没什么好说的,你自己都可以写,查注册表贝
ProgIDFromCLSID() 由 CLSID 得到 ProgID,调用者使用完成后要释放 ProgID 的内存(注5)
CoCreateGuid() 随机生成一个 GUID
IsEqualGUID()、IsEqualCLSID()、IsEqualIID() 比较2个ID是否相等
StringFromCLSID()、StringFromGUID2()、StringFromIID() 由 CLSID,IID 得到注册表中CLSID样式的字符串,注意释放内存

2,接口(interface)

        QueryInterface函数被放在所有VTA(虚函数表)的开头,用来从一个表查找另一个表.

                                          

                                                           COM Interface structure

1、函数是通过 VTAB 虚函数表提供其地址, 从另一个角度来看,不管用什么语言开发,编译器产生的代码都能生成这个表。这样就实现了组件的“二进制特性”轻松实现了组件的跨语言要求。
2、假设有一个指针型变量保存着 VTAB 的首地址,则这个变量就叫“接口指针”(注6), 变量命名的时候,习惯上加上"I"开头。另外为了区分不同的接口,每个接口 也都要有一个名字,该名字就和 CLSID 一样,使用 GUID 方式,叫 IID。
3、接口一经发表,就不能再修改了。不然就会出现向前兼容的问题。这个性质叫“接口不变性”。
4、组件中必须有3个函数,QueryInterface、AddRef、Release,它们3个函数也组成一个接口,叫"IUnknown"。任何接口都继承自IUnknown.
5、在任何接口上,调用表中的第一个函数,其实就是调用 QueryInterface()函数,就得到你想要的另外一个接口指针。这个性质叫“接口的传递性”
6、通过类型库实现接口声明的独立性.

posted on 2009-10-21 09:41  Joshua Leung  阅读(438)  评论(0编辑  收藏  举报

导航