COM 组件设计与应用(02)—GUID 和 接口

合集下载

接口设计方案 (2)

接口设计方案 (2)

接口设计方案
接口设计方案是指在软件开发中对于接口的设计和规范的
方案。

接口设计方案的目的是为了保证软件系统的可扩展性、可维护性和可重用性。

以下是一个常见的接口设计方案:
1. 定义接口的目的和功能:明确接口的用途和功能,以便
后续的开发工作能够围绕这些目标进行。

2. 确定接口的输入和输出:确定接口的输入参数和返回值,包括数据类型、格式和范围。

3. 定义接口的方法和操作:确定接口需要实现的具体方法
和操作,包括接口的名称、参数列表和返回值。

4. 定义接口的约束和限制:确定接口的约束和限制条件,
包括输入参数的合法性检查、返回值的有效性判断等。

5. 设计接口的文档和示例:编写接口的详细文档和示例代码,以便其他开发人员能够正确使用和调用接口。

6. 进行接口的测试和验证:编写测试用例对接口进行测试
和验证,确保接口的功能和性能满足需求。

7. 更新和维护接口的版本:根据需求的变化和用户的反馈,对接口进行更新和维护,并维护接口的版本管理。

总之,一个好的接口设计方案应该能够清晰地定义接口的
功能和操作,提供详细的接口文档和示例代码,以及进行
严格的测试和验证。

接口设计方案的目标是为了确保接口
的正确性、可用性和可维护性,同时提高软件系统的可扩
展性和重用性。

COM接口协议

COM接口协议

COM接口协议协议名称:COM接口协议一、概述COM(Component Object Model)接口协议是一种用于在不同软件组件之间进行通信和交互的标准协议。

本协议旨在规范COM接口的定义、使用和实现,以确保不同组件之间的互操作性和可扩展性。

二、术语定义1. COM接口:指由COM组件提供的一组方法和属性,用于与其他COM组件进行通信和交互。

2. COM组件:指实现了COM接口的软件组件,可以是动态链接库(DLL)或可执行文件(EXE)等形式。

3. 客户端:指使用COM接口的组件,通过调用COM接口的方法和属性与COM组件进行交互。

4. 服务器:指提供COM接口的组件,响应客户端的请求并执行相应的操作。

三、COM接口定义规范1. 接口标识符(IID):每个COM接口都有一个唯一的IID,用于在运行时标识接口。

IID由128位的全局唯一标识符(GUID)表示。

2. 接口定义语言(IDL):用于描述COM接口的语言,包括接口名称、方法、属性、参数等信息。

IDL使用接口定义语句(interface)进行定义。

3. 接口继承:COM接口支持单继承,一个接口可以继承自另一个接口,并可以添加新的方法和属性。

4. 接口版本管理:接口的版本号由主版本号、次版本号和修订号组成,每次对接口进行修改时,需要递增相应的版本号。

5. 接口文档:每个COM接口都应该提供详细的接口文档,包括接口的功能、方法的使用说明、参数的含义和返回值等信息。

四、COM接口使用规范1. 接口调用方式:客户端通过获取COM组件的接口指针,调用接口的方法和属性来与COM组件进行交互。

2. 接口生命周期管理:客户端在使用完COM接口后,需要调用接口的释放方法(Release)来释放接口所占用的资源。

3. 接口错误处理:COM接口的方法在执行过程中可能会返回错误代码,客户端需要根据错误代码进行相应的错误处理。

4. 接口版本兼容性:COM接口的修改应该保持向后兼容性,即新版本的接口可以与旧版本的客户端兼容,反之亦然。

组件和接口

组件和接口

组件和接口一.组件COM,即组件对象模型是微软公司为了更加符合人的行为方式开发的。

在COM下,人们可以开发出功能专一的组件,将它们组合起来,构成复杂的应用系统好处:1. 将系统中的组件用新的替换掉,以便随时进行系统的升级和定制(//360下载安全补丁)。

2. 可以在多个应用系统中重复利用同一个组件;COM与语言,平台无关,所有的程序员均可充分用自己擅长的语言写组件模块。

COM是开发软件组件的一种方法。

组件:实际上是一些小的二进制可执行程序。

开发自定义的COM组件就如同开发动态的,面向对象的API。

多个COM对象可以连接起来。

并且组件可以在运行时刻,在不被重新链接或编译应用程序的情况下,被卸下或替换掉。

Microsoft的许多技术,如ActiveX, DirectX以及OLE等都是基于COM。

用COM组件来定制应用程序。

COM并不是一个大的API,它实际上象面向对象编程方法那样,也是一种编程方法。

没有组件:生成应用程序之后,在对下一个版本重新编译并发行新生成的版本之前,应用程序一般不会发生任何变化。

必须等到整个应用程序被重新生成。

使用组件:此时的应用程序可以随新组件不断取代旧的组件而渐趋完善。

1)传统的做法是将应用程序分割成文件,模块或类,然后将它们编译并链接成一个单模应用程序。

2)它与组件建立应用程序的过程(称为组件构架)有很大的不同。

一个组件同一个应用程序类似,即都是已经编译链接好并可以使用的二进制代码。

单模应用程序只有一个二进制代码模块。

自定义组件可以在运行时刻同其他的组件连接起来以构成某个应用程序。

在需要对应用程序进行修改或改进时,只需要将构成此应用程序的组件中的某个用新的版本替换掉即可。

COM,即组件对象模型,是关于如何建立组件以及如何通过组件建立应用程序的一个规范,说明了如何可动态交替更新组件。

使用组件的优点:组件架构的一个优点就是应用可以随时间的流逝而发展进化。

除此之外,使用组件还有一些可以使对以有应用的升级更加方便和灵活的优点,如应用的定制,组件库以及分布式组件等。

com 原理

com 原理

com 原理COM原理。

COM(Component Object Model)是一种面向对象的组件技术,它是微软公司在Windows操作系统中广泛应用的一种软件组件模型。

COM组件是一种可以被其他程序使用的独立的、可重用的软件单元,它可以以二进制形式存在于文件中,也可以作为动态链接库(DLL)的一部分存在。

COM组件可以被多种编程语言(如C++、Visual Basic、Delphi等)调用和使用,因此在Windows平台上得到了广泛的应用。

COM的核心思想是将软件功能划分为独立的组件,每个组件可以独立开发、测试、部署和维护。

这种模块化的设计思想使得软件开发变得更加灵活和高效,同时也方便了软件的升级和维护。

在COM中,每个组件都有自己的接口(Interface),其他程序可以通过调用这些接口来访问组件提供的功能。

这种基于接口的设计使得不同组件之间可以进行灵活的交互和组合,从而实现更加复杂的功能。

在COM中,组件之间的通信是通过接口调用来实现的。

每个COM组件都有一个或多个接口,每个接口都定义了一组相关的功能。

当一个程序需要使用某个组件的功能时,它首先需要获取该组件的接口指针,然后通过接口指针来调用组件提供的功能。

这种基于接口的通信机制使得组件之间的耦合度降低,同时也提高了系统的灵活性和可维护性。

COM组件的生命周期是由它的引用计数来管理的。

当一个程序需要使用某个组件时,它会通过接口指针来获取该组件的引用,并将引用计数加一;当不再需要使用该组件时,程序会释放该组件的引用,并将引用计数减一。

当引用计数减为零时,系统会自动销毁该组件,释放其占用的资源。

这种基于引用计数的内存管理机制使得COM组件的使用更加安全和高效。

在COM中,组件的注册是通过注册表(Registry)来实现的。

当一个COM组件被安装到系统中时,它会在注册表中创建相应的条目,包括组件的CLSID (Class Identifier)、接口的IID(Interface Identifier)等信息。

构件对象模型COM

构件对象模型COM

COM基础
功能: (1)实现客户方与服务器方COM应用的创建过程 (2)COM通过注册表查找本地服务器(即EXE程序)
以及程序名与CLSID的转换 (3)提供标准的内存控制方法
DCOM的实现提供了分布式环境下的通信机制
在操作系统层次 以DLL文件的形式存在
6
(5) COM特性
COM基础
•语言无关性
构件引用记数
对象1
对象2
对象引用记数
对象引用记数
接口
接口引用记数
接口
接口引用记数
接口
接口引用记数
接口
接口引用记数
18
(3)接口查询
COM基础
一个COM对象(构件)可以实现多个接口 使用QueryInterface查询某个构件是否支持某个特定的接口
• QueryInterface的使用
void foo(Iunknown * pI){
内存管理函数:
CoTaskMemAlloc CoTaskMemRealloc CoTaskMemFree CoGerMalloc
COM基础
31
(3) 类厂(Class Factory)
COM基础
能够创建其他构件的构件 (构件厂) 其本身也是一个COM对象 支持一个特殊的接口 IClassFacroty 每一个COM对象类应该有一个相应的类厂对象
•数据库 OLE DB/ADO 以 COM 的方式 为数据访问提供一致的接口
•Internet ActiveX包含了所有基于COM的Internet相关技术
•COM+ 增加MTS等服务
8
2 COM接口
COM基础
COM接口是COM规范的核心内容

COM组件设计与应用之GUID和接口

COM组件设计与应用之GUID和接口

一、前言书接上回,话说在doc(Word) 复合文件中,已经解决了保存xls(Excel) 数据的问题了。

那么,接下来又要解决另一个问题:当WORD 程序读取复合文件,遇到了xls 数据的时候,它该如何启动Excel 呢?启动后,又如何让Excel 自己去读入、解析、显示xls 数据呢?二、CLSID 概念有一个非常简单的解决方案,那就是在对象数据的前面,保存有处理这个数据的程序名。

(见下图左上)图一、CLSID 的概念这的确是一个简单的方法,但同时问题也很严重。

在“张三”的计算机上,Excel 的路径是:"c:\office\Excel.exe",如果把这个.doc 文件复制到“李四”的计算机上使用,而“李四”的Excel 的路径是:"d:\Program files\Microsoft Office\Office\Excel.exe",完蛋了于是,微软想出了一个解决方案,那就是不使用直接的路径表示方法,而使用一个叫CLSID(注1)的方式间接描述这些对象数据的处理程序路径。

CLSID 其实就是一个号码,或者说是一个16字节的数。

观察注册表(上图),在HKCR\CLSID\{......}主键下,LocalServer32(DLL组件使用InprocServer32)中保存着程序路径名称。

CLSID 的结构定义如下:typedef struct _GUID {DWORD Data1; // 随机数WORD Data2; // 和时间相关WORD Data3; // 和时间相关BYTE Data4[8]; // 和网卡MAC相关} GUID;typedef GUID CLSID; // 组件IDtypedef 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}用一个号码间接表示程序名,的确是个Good idea,实现了组件位置的透明性,并方便地扩展出DCOM (远程组件)。

guid的组成

guid的组成

guid的组成GUID(全局唯一标识符)是一种由计算机系统生成的标识符,用于唯一标识对象或实体。

它由一串数字和字母组成,通常呈现为32个字符的十六进制数。

GUID的组成是由多个因素决定的,下面将详细介绍。

首先,GUID的组成包括时间戳。

时间戳是指GUID生成的时间,通常以自1970年1月1日以来的毫秒数表示。

时间戳确保了GUID的唯一性,因为每个时间戳都是不同的,这样就避免了重复生成相同的GUID。

其次,GUID的组成还包括计算机的唯一标识符。

计算机的唯一标识符是指计算机硬件或操作系统生成的一个唯一的标识符,用于区分不同的计算机。

这个标识符通常是根据计算机的硬件信息或操作系统的特征生成的,确保了在不同的计算机上生成的GUID也是唯一的。

另外,GUID的组成还包括一个随机数。

随机数是指在生成GUID 时,计算机系统会生成一个随机的数值,用于增加GUID的随机性和唯一性。

随机数的引入使得即使在同一时间戳和计算机标识符下,生成的GUID也是不同的。

最后,GUID的组成还包括一个校验位。

校验位是指在生成GUID 时,计算机系统会根据前面的组成部分计算出一个校验值,用于验证GUID的正确性。

校验位的引入可以确保生成的GUID没有错误或损坏,提高了GUID的可靠性。

综上所述,GUID的组成包括时间戳、计算机的唯一标识符、随机数和校验位。

这些因素的综合作用使得生成的GUID具有全局唯一性和随机性,可以在计算机系统中广泛应用于唯一标识对象或实体的需求。

GUID的组成保证了生成的标识符不会重复,同时也提高了标识符的可靠性和安全性。

在现代计算机系统中,GUID已经成为一种重要的标识符生成方式,被广泛应用于各种领域,如数据库管理、分布式系统等。

GUID详解

GUID详解

在USB编程之前要事先了解一下GUID的概念。

应用其他网页中的定义:全球唯一标识符(GUID) 是一个字母数字标识符,用于指示产品的唯一性安装。

在许多流行软件应用程序(例如Web 浏览器和媒体播放器)中,都使用GUID。

GUID 的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个x 是0-9 或a-f 范围内的一个十六进制的数字。

例如:6F9619FF-8B86-D011-B42D-00C04FC964FF 即为有效的GUID 值。

在计算机领域有很多东西需要不重复的唯一标识的东西,例如设备的类型,类,接口标识,目录名等等。

这是个天文数字,我记得是有工具能自动生成这个GUID码的,反正不同地点,不同时间,生成相同的GUID的可能性很小很小很小,小到什么程度,没查过,基本上可以认为是不可能生成相同的GUID值的。

计算机中有各种个样的设备类型,这些设备类型被微软用固定的GUID来标识了,这些GUID 对实际编程是有很大关系的,用错了会麻烦,我查了一下文档,把查到的设备类型的GUID 列在下面供大家参考:1394 Host Bus ControllerClass = 1394ClassGuid = {6bdd1fc1-810f-11d0-bec7-08002be2092f}This class includes system-supplied drivers of 1394 host controllers connected on a PCI bus, but not drivers of 1394 peripherals.Battery DevicesClass = BatteryClassGuid = {72631e54-78a4-11d0-bcf7-00aa00b7b32a}This class includes drivers of battery devices and UPSes.CD-ROM DrivesClass = CDROMClassGuid = {4d36e965-e325-11ce-bfc1-08002be10318}This class includes drivers of CD-ROM drives, including SCSI CD-ROM drives. By default, the system's CD-ROM class installer also installs a system-supplied CD audio driver and CD-ROM changer driver as PnP filters.Disk DrivesClass = DiskDriveClassGuid = {4d36e967-e325-11ce-bfc1-08002be10318}This class includes drivers of hard disk drives. See also the HDC and SCSIAdapter classes.Display AdaptersClass = DisplayClassGuid = {4d36e968-e325-11ce-bfc1-08002be10318}This class includes drivers of video adapters, including display drivers and video miniports.Floppy Disk ControllersClass = FDCClassGuid = {4d36e969-e325-11ce-bfc1-08002be10318}This class includes drivers of floppy disk drive controllers.Floppy Disk DrivesClass= FloppyDiskClassGuid= {4d36e980-e325-11ce-bfc1-08002be10318}This class includes drivers of floppy drives.Hard Disk ControllersClass = HDCClassGuid = {4d36e96a-e325-11ce-bfc1-08002be10318}This class includes drivers of hard disk controllers, including ATA/ATAPI controllers but not SCSI and RAID disk controllers.Human Input Devices (HID)Class = HIDClassClassGuid = {745a17a0-74d3-11d0-b6fe-00a0c90f57da}This class includes devices that export interfaces of the HID class, including HID keyboard and mouse devices, which the installed HID device drivers enumerate as their respective "child" devices. (See also the Keyboard or Mouse classes later in this list.)Imaging DeviceClass = ImageClassGuid = {6bdd1fc6-810f-11d0-bec7-08002be2092f}This class includes drivers of still-image capture devices, digital cameras, and scanners.IrDA DevicesClass = InfraredClassGuid = {6bdd1fc5-810f-11d0-bec7-08002be2092f}This class includes Serial-IR and Fast-IR NDIS miniports, but see also the Network Adapter class for other NDIS NIC miniports.KeyboardClass = KeyboardClassGuid = {4d36e96b-e325-11ce-bfc1-08002be10318}This class includes all keyboards. That is, it also must be specified in the (secondary) INF for an enumerated "child" HID keyboard device.Medium ChangersClass= MediumChangerClassGuid= {ce5939ae-ebde-11d0-b181-0000f8753ec4}This class includes drivers of SCSI media changer devices.Memory Technology DriverClass = MTDClassGUID = {4d36e970-e325-11ce-bfc1-08002be10318}This class includes drivers for memory devices, such as flash memory cards.MultimediaClass = MediaClassGuid = {4d36e96c-e325-11ce-bfc1-08002be10318}This class includes Audio and DVD multimedia devices, joystick ports, and full-motion video-capture devices.ModemClass = ModemClassGuid = {4d36e96d-e325-11ce-bfc1-08002be10318}This class installs modems. An INF for a device of this class installs no device driver(s), but rather specifies the features and configuration information of a particular modem and stores this information in the registry. See also the Multifunction class.MonitorClass = MonitorClassGuid = {4d36e96e-e325-11ce-bfc1-08002be10318}This class includes display monitors. An INF for a device of this class installs no device driver(s), but rather specifies the features of a particular monitor to be stored in the registry for use by drivers of video adapters. (Monitors are enumerated as the child devices of display adapters.)MouseClass = MouseClassGuid = {4d36e96f-e325-11ce-bfc1-08002be10318}This class includes all mice and other kinds of pointing devices, such as trackballs. That is, it also must be specified in the (secondary) INF for an enumerated "child" HID mouse device.Multifunction DevicesClass = MultifunctionClassGuid = {4d36e971-e325-11ce-bfc1-08002be10318}This class includes combo cards, such as a PCMCIA modem and netcard adapter. The driver for such a PnP multifunction device is installed under this class and enumerates the modem and netcard separately as its "child" devices.Multi-port Serial AdaptersClass = MultiportSerialClassGuid = {50906cb8-ba12-11d1-bf5d-0000f805f530}This class includes intelligent multiport serial cards, but not peripheral devices that connect to its ports. It does not include unintelligent (16550-type) mutiport serial controllers or single-port serial controllers (see the Ports class).Network AdapterClass = NetClassGuid = {4d36e972-e325-11ce-bfc1-08002be10318}This class includes NDIS NIC miniports excluding Fast-IR miniports, NDIS intermediate drivers (of "virtual adapters"), and CoNDIS MCM miniports.Network ClientClass = NetClientClassGuid = {4d36e973-e325-11ce-bfc1-08002be10318}This class includes network and/or print providers.Network ServiceClass = NetServiceClassGuid = {4d36e974-e325-11ce-bfc1-08002be10318}This class includes network services, such as redirectors and servers.Network TransportClass = NetTransClassGuid = {4d36e975-e325-11ce-bfc1-08002be10318}This class includes NDIS protocols, CoNDIS stand-alone call managers, and CoNDIS clients, as well as higher level drivers in transport stacks.PCMCIA AdaptersClass = PCMCIAClassGuid = {4d36e977-e325-11ce-bfc1-08002be10318}This class includes system-supplied drivers of PCMCIA and CardBus host controllers, but not drivers of PCMCIA or CardBus peripherals.Ports (COM & LPT serial ports)Class = PortsClassGuid = {4d36e978-e325-11ce-bfc1-08002be10318}This class includes drivers of serial or parallel port devices, but see also the MultiportSerial class.PrinterClass = PrinterClassGuid = {4d36e979-e325-11ce-bfc1-08002be10318}This class includes printers.SCSI and RAID ControllersClass = SCSIAdapterClassGuid = {4d36e97b-e325-11ce-bfc1-08002be10318}This class includes SCSI HBA miniports and disk-array controller drivers.Smart Card ReadersClass = SmartCardReaderClassGuid = {50dd5230-ba8a-11d1-bf5d-0000f805f530}This class includes drivers for smart card readers.Storage VolumesClass = V olumeClassGuid = {71a27cdd-812a-11d0-bec7-08002be2092f}This class includes storage volumes as defined by the system-supplied logical volume manager and class drivers that create device objects to represent storage volumes, such as the system disk class driver.System DevicesClass = SystemClassGuid = {4d36e97d-e325-11ce-bfc1-08002be10318}This class includes the Windows® 2000 HALs, system bus drivers, the system ACPI driver, and the system volume-manager driver. It also includes battery drivers and UPS drivers.Tape DrivesClass = TapeDriveClassGuid = {6d807884-7d21-11cf-801c-08002be10318}This class includes drivers of tape drives, including all tape miniclass drivers.USBClass = USBClassGuid = {36fc9e60-c465-11cf-8056-444553540000}This class includes system-supplied (bus) drivers of USB host controllers and drivers of USB hubs, but not drivers of USB peripherals.The following classes and GUIDs should not be used to install devices (or drivers) on Windows 2000 platforms:AdapterClass = AdapterClassGUID = {4d36e964-e325-11ce-bfc1-08002be10318}This class is obsolete.APMClass = APMSupportClassGUID = {d45b1c18-c8fa-11d1-9f77-0000f805f530}This class is reserved for system use.ComputerClass = ComputerClassGUID = {4d36e966-e325-11ce-bfc1-08002be10318}This class is reserved for system use.DecodersClass = DecoderClassGUID = {6bdd1fc2-810f-11d0-bec7-08002be2092f}This class is reserved for future use.Global Positioning SystemClass = GPSClassGUID = {6bdd1fc3-810f-11d0-bec7-08002be2092f}This class is reserved for future use.No driverClass = NoDriverClassGUID = {4d36e976-e325-11ce-bfc1-08002be10318}This class is obsolete.Non-Plug and Play DriversClass = LegacyDriverClassGUID = {8ecc055d-047f-11d1-a537-0000f8753ed1}This class is reserved for system use.Other DevicesClass = UnknownClassGUID = {4d36e97e-e325-11ce-bfc1-08002be10318}This class is reserved for system use. Enumerated devices for which the system cannot determine the type are installed under this class. Do not use this class if you're unsure in which class your device belongs; either determine the correct device setup class or create a new class.Printer UpgradeClass = Printer UpgradeClassGUID = {4d36e97a-e325-11ce-bfc1-08002be10318}This class is reserved for system use.SoundClass = SoundClassGUID = {4d36e97c-e325-11ce-bfc1-08002be10318}This class is obsolete.USB Mass Storage DeviceClassGUID = a5dcbf10-6530-11d2-901f-00c04fb951ed。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

COM组件设计与应用(二)GUID 和接口作者:杨老师一、前言书接上回,话说在doc(Word) 复合文件中,已经解决了保存xls(Excel) 数据的问题了。

那么,接下来又要解决另一个问题:当WORD 程序读取复合文件,遇到了xls 数据的时候,它该如何启动Excel 呢?启动后,又如何让Excel 自己去读入、解析、显示xls 数据呢?二、CLSID 概念有一个非常简单的解决方案,那就是在对象数据的前面,保存有处理这个数据的程序名。

(见下图左上)图一、CLSID 的概念这的确是一个简单的方法,但同时问题也很严重。

在“张三”的计算机上,Excel 的路径是:"c:\office\Excel.exe",如果把这个doc 文件复制到“李四”的计算机上使用,而“李四”的Excel 的路径是:"d:\Program files\Microsoft Office\Office\Excel.exe",完蛋了:-(于是,微软想出了一个解决方案,那就是不使用直接的路径表示方法,而使用一个叫CLSID (注1)的方式间接描述这些对象数据的处理程序路径。

CLSID 其实就是一个号码,或者说是一个16字节的数。

观察注册表(上图),在HKCR\CLSID\{......}主键下,LocalServer32(DLL组件使用InprocServer32)中保存着程序路径名称。

CLSID 的结构定义如下:typedef struct _GUID {DWORD Data1; // 随机数WORD Data2; // 和时间相关WORD Data3; // 和时间相关BYTE Data4[8]; // 和网卡MAC相关} GUID;typedef GUID CLSID; // 组件IDtypedef 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}用一个号码间接表示程序名,的确是个Good idea,实现了组件位置的透明性,并方便地扩展出DCOM(远程组件)。

但,但,但,但.....CLSID 有16个字节共128位二进制数,干吗用这么长的数字呀?遥想当年......我还在上幼儿园的时候,人们设计了socket,用TCP/IP 协议进行网络通讯。

每个参与通讯的计算机都有一个4字节的IP 表示编号地址,范围是0,0,0,0 ~ 255,255,255,255 共42亿个地址。

可是没想到啊,没想到,自从Internet 选择了TCP/IP 协议后,42亿个地址就不够全世界的劳动人民分配啦。

除了劳动人民,还有冰箱、彩电、电饭锅、手机、手提电脑......这些都需要连网呀。

在办公室通过网络开启电饭锅给我焖饭,下班回家后就能吃现成的啦,多幸福呀?!(注:在我们家老婆是领导,所以是我做饭。

咳......)由于前车之鉴,微软这次设计CLSID/IID 就使用了GUID概念的16个字节,这下好啦,全世界60亿人口,每个人每秒钟分配10亿个号码,那么需要分配1800亿年。

反正等到地球没有了都不会使用完的:-)三、产生CLSID1.如果使用开发环境编写组件程序,则IDE会自动帮你产生CLSID;2.你可以手工写CLSID,但千万不要和人家已经生成的CLSID 重复呀,所以严重地不推荐;(可是微软的CLSID都是手工写的,这叫“只许州官放火,不许百姓点灯”);3.程序中,可以用函数CoCreateGuid() 产生CLSID;4.使用工具产生GUID(注2);vc6.0版本运行:"vc目录\Common\Tools\GuidGen.exe"程序(你可以参照上回文章中介绍的方法,把这个工具程序加到开发环境中,方便调用)。

版本,在菜单“工具\创建GUID”中,就可以执行了。

四、ProgID 概念每一个COM组件都需要指定一个CLSID,并且不能重名。

它之所以使用16个字节,就是要从概率上保证重复是“不可能”的。

但是,(世界上就怕“但是”二字)微软为了使用方便,也支持另一个字符串名称方式,叫ProgID(注3)。

见上图注册表的ProgID 子键内容(注4)。

由于CLSID 和ProgID 其实是一个概念的两个不同的表示形式,所以我们在程序中可以随便使用任何一种。

(有些人就是讨厌,说话不算数。

明明GUID 的目的就是禁止重复,但居然又允许使用ProgID?!ProgID 是一个字符串的名字,重复的可能性就太大了呀。

赶明儿我也写个程序,我打算这个程序的ProgID 叫“Excel.Application”,嘿嘿)下面介绍一下CLSID 和ProgID 之间的转换方法和相关的函数:五、接口(Interface)的来历到此,我们已经知道了CLSID 或ProgID 唯一地表示一个组件服务程序,那么根据这些ID,就可以加载运行组件,并为客户端程序提供服务了。

(启动组件程序的方法,会陆续介绍)。

接下来先讨论如何调用组件提供的函数?-----接口。

作为客户端程序员,它希望或者说他要求:我的程序只写一次,然后不做任何修改就可以调用任意一个组件。

举例来说:1.你可以在Word 中嵌入Excel,也可以嵌入Picture,也可以嵌入任何第三方发表的ActiveX 文档......也就是说,连Word 自己都不知道使用它的人将会在doc 里面插入什么东东;2.你可以在HTML 文件中插入一个ActiveX,也可以插入一个程序脚本Script,......你自己写的插件也可以插入到IE 环境中。

为了完成你的功能,你绝对也不会去让微软修改IE 吧?!这个要求实在有点难度,Office 开发停滞了。

说来话巧,一天老O(Office 项目的总工程师)和小B(VB 项目的总工程师)一起喝酒,老O向小B倾诉了他的烦恼:老O:怎么能让我写的程序C,可以调用其它人写的程序S中的函数?(C表示客户程序,S表示提供服务的程序)小B:你是不是喝糊涂了?让S作成DLL,你去LoadLibrary()、GetProcAddress()、...FreeLibrary()?!老O:废话!要是这么简单就好了。

问题是,连我都不知道这个S程序是干什么的?能干什么?我怎么调用呀?小B:哦......这个比较高级,但我现在不能告诉你,因为我怕你印象不深。

老O:~!·#¥%……—*......小B:是这样的,在VB中,我们制定了一个标准,这个标准允许任何一个VB开发者,把他自己写的某个功能的小程序放在VB的工具栏上,这样就好象他扩展了VB 的功能一样。

老O:哦?就是那个叫什么VBX 的滥玩意儿?小B:我呸......别看VBX 这个东西不起眼儿,的确我也没看上它。

但你猜怎么着?现在有成千上万的VB 程序爱好者把他们写的各式各样功能的VBX 小程序,放到网上,让大家共享那。

老O:哦~~~,那你们的这个VBX 标准是什么?小B:嘿嘿......其实特简单,就是在VBX 中必须实现7个函数,这7个函数名称和功能必须是:初始化、释放、显示、消息处理......,而至于它内部想干什么,我也管不着。

我只是在需要的时候调用我需要的这7个函数。

老O:哦~~~,这样呀......对了,我现有个急事,我先走了。

88,你付帐吧......小B:喂!喂喂...... 走这么急干什么,钱包都掉了:-)老O虽然丢了钱包,仍然兴奋地冲回办公室,他开始了思考......1、我的程序C,要能调用任何人写的程序B。

那么B必须要按照我事先的要求,提供我需要的函数F1(),F2(),F3(),K1(),K2()。

2、BASIC 是解释执行,因此它的函数不用考虑书写顺序,只要给出函数名,解释器就能找到。

但我使用的是C++呀......3、C++编译后的代码中没有函数名,只有函数地址,因此我必须改进为用VTAB(虚函数表)表示函数入口:图二、VTAB 的结构4、还不够好,需要改进一下,因为所有的函数地址都放在一个表中会不灵活、不好修改、不易扩展。

恩,有了!按照函数功能的类型进行分类:图三、多个VTAB 的结构5、问题又来了,现在有2个VTAB 虚函数表,那么怎么能够从一个表找到另一个表那?恩又有办法了,我要求你必须要实现一个函数,并且这个函数地址必须放在所有表的开头(表中的第一个函数指针),这个函数就叫QueryInterface()吧,完成从一个表查找到另一个表的功能:(除了QueryInterface()函数,顺便也完成另外两个函数,叫AddRef() 和Release()。

这两个函数的功能以后再说)图四、COM 接口结构6、为了以后描述方便,不再使用上图(图四)的方法了,而使用图五这样简洁的样式:图五、COM 接口结构的简洁图示六、接口(Interface)概念1、函数是通过VTAB 虚函数表提供其地址,从另一个角度来看,不管用什么语言开发,编译器产生的代码都能生成这个表。

这样就实现了组件的“二进制特性”轻松实现了组件的跨语言要求。

2、假设有一个指针型变量保存着VTAB 的首地址,则这个变量就叫“接口指针”(注6),变量命名的时候,习惯上加上"I"开头。

另外为了区分不同的接口,每个接口也都要有一个名字,该名字就和CLSID 一样,使用GUID 方式,叫IID。

3、接口一经发表,就不能再修改了。

不然就会出现向前兼容的问题。

这个性质叫“接口不变性”。

4、组件中必须有3个函数,QueryInterface、AddRef、Release,它们3个函数也组成一个接口,叫"IUnknown"。

(注7)5、任何接口,其实都包含了IUnknown 接口。

随着你接触到更多的接口就会了更体会解到接口的另一个性质“继承性”。

6、在任何接口上,调用表中的第一个函数,其实就是调用QueryInterface()函数,就得到你想要的另外一个接口指针。

相关文档
最新文档