COM组件设计与应用(二)

本文详细介绍了CLSID和ProgID的概念及其在COM组件中的作用。包括CLSID的结构定义、产生方法、与ProgID之间的转换及相关的函数,以及接口(Interface)的基本概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CLSID 的结构定义如下:
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}


三、产生 CLSID
 
1. 如果使用开发环境编写组件程序,则IDE会自动帮你产生 CLSID;
2. 你可以手工写 CLSID,但千万不要和人家已经生成的 CLSID 重复呀,所以严重地不推荐;(可是微软的CLSID

都是
手工写的,这叫“只许州官放火,不许百姓点灯”) ;
3. 程序中,可以用函数 CoCreateGuid() 产生 CLSID;
4. 使用工具产生 GUID(注2);
vc6.0版本运行:"vc目录/Common/Tools/GuidGen.exe"程序(你可以参照上回文章中介绍的方法,把这个工具程序
加到开发环境中,方便调用)。vc.net版本,在菜单“工具/创建GUID”中,就可以执行了。


四、ProgID 概念
  每一个COM组件都需要指定一个 CLSID,并且不能重名。它之所以使用16个字节,就是要从概率上保证重
复是“不可能”的。但是,(世界上就怕“但是”二字)微软为了使用方便,也支持另一个字符串名称方式,叫

ProgID


下面介绍一下 CLSID 和 ProgID 之间的转换方法和相关
的函数:
函数功能说明
CLSIDFromProgID()、CLSIDFromProgIDEx() 由 ProgID 得到 CLSID。没什么好说的,你自己都可以写,查注册表


ProgIDFromCLSID() 由 CLSID 得到 ProgID,调用者使用完成后要释放 ProgID 的内存(注5)
CoCreateGuid() 随机生成一个 GUID
IsEqualGUID()、IsEqualCLSID()、IsEqualIID() 比较2个ID是否相等
StringFromCLSID()、StringFromGUID2()、
StringFromIID()
由 CLSID,IID 得到注册表中CLSID样式的字符串,注意释放内存


六、接口(Interface)概念
1、函数是通过 VTAB 虚函数表提供其地址, 从另一个角度来看,不管用什么语言开发,编译器产生的代码都能生
成这个表。这样就实现了组件的“二进制特性”轻松实现了组件的跨语言要求。
2、假设有一个指针型变量保存着 VTAB 的首地址,则这个变量就叫“接口指针”(注6), 变量命名的时候,习惯


加上"I"开头。另外为了区分不同的接口,每个接口也都要有一个名字,该名字就和 CLSID 一样,使用 GUID 方
式,叫 IID。
3、接口一经发表,就不能再修改了。不然就会出现向前兼容的问题。这个性质叫“接口不变性”。
4、组件中必须有3个函数,QueryInterface、AddRef、Release,它们3个函数也组成一个接口,叫"IUnknown"。(

注7)
5、任何接口,其实都包含了 IUnknown 接口。随着你接触到更多的接口就会了更体会解到接口的另
一个性质“继承性”。
6、在任何接口上,调用表中的第一个函数,其实就是调用 QueryInterface()函数,就得到你想要的另外一个接口
指针。这个性质叫“接口的传递性”
7、C/C++语言中需要事先对函数声明,那么就会要求组件也必须提供C语言的头文件。不行!为了能使COM具有
跨语言的能力,决定不再为任何语言提供对应的函数接口声明,而是独立地提供一个叫类型库(TLB)的声明。每
个语言的IDE环境自己去根据TLB生成自己语言需要的包装。这个性质叫“接口声明的独立性”(注8)

留作业啦......
1、IDispatch 接口的 IID 是多少?(哎~~~ 笨笨,在源程序中,用鼠标右键执行Go to definition 呀)
2、IPicture 接口有几个函数?功能是什么?(别玩了!你多大了?想不想在程序中显示 JPG 图像呀,看 MSDN 去)
  想知道为什么COM函数总是返回 HRESULT 吗?想知道如何使用 BSTR、VARIANT 吗?想知道 COM 中应该如
何使用内存吗?想知道如何使用 UNICODE 吗?......恩~~~,我现在不能告诉你,我现在告诉你,怕你印象不深!
且听下回分解......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值