COM轻松入门

读者: 685    发布时间: 2008

原文: A Friendly Approach to COM Basics

Introduction

This article describes about the simple basics of the ever time evolution in the history of programming, the COM. I think it's useful to the beginners who have no idea about this technology. This is simple and friendly, at least I think...

COM addresses software design in a pragmatic way by designing most commercially proven aspects of classical object orientation.. If you are a developer on Windows then you can't live without knowing what COM is.

The basic COM features

  • COM is a specification. It describes what standards you should follow in order to create a component.
  • COM is object oriented. Each COM object has its own identity and state.
  • COM objects are black boxes.  
  • COM objects can link dynamically. Just visualize them as plug and play devices on your computer: just plug it in and it starts working. Pull it out when you don't need it.
  • COM enables you to create distributed applications too. You don’t even have to know where the COM object resides when you call it. It could even reside somewhere on a remote computer.
  • COM applications can be written in any programming language which supports pointer to a function.
  • COM components are self-versioning. This means that when you upgrade an already existing COM component, it is treated as another version of the same component. This is done because it helps to avoid any version conflicts with older clients.
  • COM components help you implement code reusability. Once a COM component is created, it can be used any number of times in any number of projects as you like.

Types of Components

  • In-process: They are in the form of (DLLs) Dynamic Link Libraries. They run in the memory space of your client application (that's why they are termed as in-process). If they crash, they crash the entire client application with them as they operate in the same memory space as that of the client application.
  • Out-process: They are in the form of (EXEs) Executables. They run in a different memory space as that of your client application (that's why they are termed as out-process). If they crash, it doesn't affect the client application as they operate in a different memory space as that of the client application.
  • Remote: Remote components are just like any other component but the only difference is that remote components run from a separate remote location via a network. They are implemented using DCOM (Distributed COM).

A little about...

COM components have a unique identity number. These numbers are stored in the registry under the HKEY_CLASSES_ROOT main key. COM is, as I explained in its features, not just a specification on paper. It also includes various APIs. It also includes some amount of system-level code. All of this is present in your COM runtime library.

The Component Object Library is itself a system component (which is usually present in your OS) which provides COM components the ability to make calls among different components within a process (in-process), across processes (out-process) or over a network (remote).

Component objects, which you create, are highly encapsulated. When you create a component and distribute it, the client using it can't see the implementation code. He doesn't even have access to the class you have your code in.

As I previously explained, COM objects are black boxes. Although they represent reusable components, reusability is not possible in the fashion of object-oriented languages. COM objects can contain other COM objects and delegate the implementation of specific interfaces to other COM objects. However you cannot derive an object from an existing object in the fashion of deriving a class from a base class in C++.

If this is the case then how does the client use your component to access the services in it? Well, here is where the concept of interfaces jumps in. Every component has an interface, which it has to implement. That interface do not carry any implementations of the methods: those are present in the Co-Class (Component Class). The interface simply contains the method declarations. The interface is the only way a client can access the services of the component.

Now interfaces are implemented using VTables. The VTable contains an array of pointers. These pointers in turn point to the functions of the component. When you create an object of the component in your code, it also creates its VTable in memory.

All COM objects implement a specific interface IUnknown. Through this interface, information about other interfaces a COM object may support can be obtained.

The client creates a pointer to the interface. That pointer points to a virtual pointer. The virtual pointer points to the VTable. Using the interface pointer and the virtual pointer, the client of the component can call any function in it.

There are mainly two types of interfaces:

  • Standard Interfaces: These are the interfaces provided by the COM library. Some of the standard interfaces are IUnknown, IDispatch, IClassFactory, IOle, IDataObject, IStream and IStorage.
  • Custom Interfaces: These are the interfaces created by you.

The Identification of Components

As components are developed and used globally, we have to identify each component uniquely. Now how on earth do you think that this can be done? Well, the Open Software Foundation (OSF) came to the rescue and developed an algorithm that generates a unique identifier called the UUID (Universal Unique Identifier). In COM, it's called the GUID (Global Unique Identifier). The GUID is a number, which is assigned to the interface, class or a library.

COM objects are identified through GUIDs, globally unique interface identifiers. They are 128-byte numbers that are statistically unique; programmers need not worry about anyone else using the same GUID that has been generated through tools or functions provided for this purpose.

We wont get too much into the details of how this algorithm works, but let me tell you the aspects it takes into consideration when it generates that unique identifier:

  • The current date and time
  • The network adapter card address
  • The system clock
  • An automatically incremented counter

Now each COM object has a unique GUID for itself, but where are all of these GUIDs stored? They are stored in your registry. All COM classes are registered in the HKEY_CLASSES_ROOT\CLSID key. For each CLSID key, you also have a sub key called InProcServer32. The value of this sub key will be the filename of the DLL associated with this respective class.

Whenever you create a component, it will be in the form of an EXE or a DLL. You would have to register them on the machine you will be using them on. If you're distributing your component, it could be a part of the installation procedure done automatically, invisible to the user. You could also do the same manually.

A DLL (Dynamic Link Library) can be registered using the following command:

In command line:

REGSVR32 <name of Your COM DLL >

An EXE (Executable) can be registered using the following command:

<COM exe name > /REGSERVER

In this article, I tried to explain the basics and fundamentals of COM to some extent. If you have any suggestions (either positive or negative), please feel free to contact me.

 License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Renjith Ramachandran


Renjith is a simple & cool guy from kerala, A hardcore designer, programmer and a budding analyst.

He is an open source freak, among them he enjoyed some work with the mozilla firefox.

He loves to listen to music,he loves to play and watch football and long drives while playing the music.

He is the founder of INDIAN IT FORUM - www.indianITforum.com - the largest forum for indian IT professionals.

Now a days he is exploring the good old unix stuffs, because his clients needs to do some more things in to it.



Occupation: Architect
Location: India India

译文: COM轻松入门

概要

本文介绍了COM编程发展过程中的一些简单原则。对那些对COM一无所知的初学者来说我觉得会有所帮助。这篇入门简单和轻松,我觉得...

通过大多数的商业性的经典面向对象设计,COM被证明是设计软件的一种务实的方法。如果你是Windows平台上开发人员,不清楚COM是不可想象的。

COM基本特点

  • COM是一个规范。它描述了创建组件(Component)是你需要遵循的规范。
  • COM是面向对象的。每个COM对象有自己的特征和状态。
  • COM对象是黑盒对象。
  • COM对象可以动态链接。就像你电脑上的即插即用设备一样。:插上就可以开始工作。不需要的时候在拔掉。
  • COM使你能够创建分布式应用。你调用COM的时候甚至不需要知道COM对象在哪。它甚至可以宿主在远程主机上。
  • 任何支持函数指针的语言都可以编写COM应用。
  • COM组件是版本独立的。这意味着当你升级一个已有组件时,它被认为是同一个组件的另一个版本。这样可以避免旧客户端的版本冲突。
  • COM组件可以实现代码复用。一旦创建了COM组件,它就可以在任何项目中无限次使用。

组件的类型

  • In-process(进程内组件): 它们都是DLL(动态链接库)形式。它们在应用程序的内存中运行(所以叫它们进程内组件)。因为它们和应用程序使用同一的内存空间,如果它们崩溃了,会导致整个应用程序崩溃。
  • Out-process(进程外组件):它们都是EXE形式。他们运行在不同于客户端程序的内存中(所以叫他们进程外组件).因为和应用程序使用不同的内存空间,如果组件崩溃了,并不会影响应用程序。
  • Remote(远程组件): 远程组件和其他组件没有两样,除了它是通过网络运行在远程机器上。它们用DCOM(分布式COM)实现。

其他...

COM组件有一个唯一标志号。它们保存在注册表的HKEY_CLASSES_ROOT主键中。像我刚才讲的,COM不只是一个文档的规范。它包含许多API,还有一些操作系统级别的代码。这些都体现在COM运行库中。

COM组件库本身是一个系统组件(一般都集成在操作系统中),使得不同组件可以在进程中(In-process)、进程外(Out-process)或远程组件(remote)相互调用。

创建的COM组件都高度封装。当创建了组件并发布,客户端只能调用但看不到实现代码。甚至不能访问你类中的代码。

就像我刚才解释的,COM组件是黑盒组件。尽快它是可重用的组件,但不是像面向对象语言那样的复用。COM组件可以包含其他COM组件,并且可以把对特定接口的实现委托其他COM组件。但是你不能像在C++中继承类一样集成COM对象。

这是不是一种客户端通过使用组件来访问服务的方式?嘿,这就是接口的概念。每个组件都有一个必须实现的接口。这个接口不实现任何方法:方法是在Co-Class(组件类)中实现。接口之包含对方法的声明。接口是客户端访问组件服务的唯一方式。

现在接口是通过VTables实现的。VTable包含一个指针数组。这些指针顺序指向组件的函数。当你用代码创建了组件的一个对象时,你同时也创建了它在内存中的VTable。

所有COM对象都实现IUnknown这个特点的接口。通过这个接口,可以得到对COM对象其他接口的信息。

客户端创建一个接口的指针。这个指针指向一个虚拟指针。这个虚拟指针指向VTable。使用接口指针和虚拟指针,客户端可以使用组件的任何函数。

接口主要有两种:

  • 标准接口:标准接口是COM库提供的。IUnknown, IDispatch, IClassFactory, IOle, IDataObject, IStream 和 IStorage是其中的一些。
  • 自定义接口:这些是自己创建的接口。

组件识别

由于组件是在全球范围内开发和使用,所以我们必须能够识别每个组件。你觉得现在是怎么解决的?其实,开源软件组织(Open Software Foundation - OSF)解决了这个问题,他们开发了一种算法可以生成一个唯一标志符,称为UUID(Universal Unique Identifier)。在COM中,它们被称为GUID(Global Unique Identifie)。GUID是一个数字,分配给每个接口、类或者库。

COM组件通过GUID来区分每个对象。它们是128位在统计学上唯一的的数字。如果GUID是通过工具或者函数生成的,则程序员不用担心会和其他人重复。

We wont get too much into the details of how this algorithm works, but let me tell you the aspects it takes into consideration when it generates that unique identifier:

我们不需要知道这个算法具体如何工作,但是我可以告诉你一些在生成GUID的算法考虑的因素:

  • 当前时间
  • 网卡物理地址
  • 系统时钟
  • 一个自增计数器

每个COM对象都有了一GUID后,这些GUID都保存在哪里?它们保持在注册表中。所有COM类都注册在HKEY_CLASSES_ROOT\CLSID下。每个CLSID,都有一个子健为InProcServer32。它的值就是这个类相关的DLL的文件名。

组件创建后,它的形式为一个EXE或者一个DLL。使用前必须注册它们。如果是发布一个组件,它可以在安装的过程中后台自动完成。你也可以手动注册。

使用下面的命令可以注册DLL(动态链接库):

REGSVR32 <name of Your COM DLL >

使用下面的命令注册EXE(可执行的程序):

<COM exe name > /REGSERVER

这篇文章,就某些方面我解释了COM的基础和基本原理。不管你有什么建议(无论好坏),尽管联系我。

版权
这篇文章没有显式的附件版权,但是文章正文或者下载的文件中可有包含有使用条款。如果有疑问可以使用下面的讨论版联系作者。

 

更多认证作者可以在这里找到。

作者介绍

Renjith Ramachandran


Renjith很酷而且单纯,他来自kerala, 硬件设计师、程序员兼做新技术研究。
他对开源软件异常热爱,参与了Mozilla Firefox的工作。
喜欢听音乐,喜欢踢足球和看足球比赛,喜欢在长途自驾时听音乐。
他是INDIAN IT FORUM - www.indianITforum.com - 印度最大的IT专业论坛 - 的创立者。

最近他在研究以前优秀Unix中的东西,因为他的客户有进一步这方面的需求。

职位: 架构师
国家: India 印度