【原创翻译】COM入门简介 -- 什么是COM , 怎样使用它 (2)

翻译 2007年10月01日 17:05:00

Introduction to COM - What It Is and How to Use It
By Michael Dunn
From www.codeproject.com

/**********原创翻译,转载请注明出处*********** 新手水平有限,欢迎批评指教 By FreeKid /

COM入门简介 -- 什么是COM , 怎样使用它 (2)

基本元素定义

让我们从头开始。简单的说,接口就是一组函数。这些函数被称作"方法"。接口的名称以大写字母'I'打头,例如"IShellLink"。在C++中,接口总被写成一个只含有纯虚函数的抽象基类。

接口可以从其它接口"继承"而来,它的机制就像C++中的单继承一样。而接口是不允许多重继承的。

COClass(Component Object Class)被包含在DLL或者EXE文件之中,并且它包含着一个或多个接口代码。COClass就是来实现这些接口的。COM对象是COClass在内存中的一个实例。虽然在通常情况下一个用来实现COM的类就是C++类,但要注意COM的"类"与C++中的"类"是不同的。

COM服务器是包含一个或多个COClass的二进制单位(DLL或者EXE)。

为了通知Windows COM服务器的位置,需要在注册表中"注册"(Registration)相应信息。同样,反注册(Unregistration)是用来消除那些注册信息的。

GUID(Globally Unique Identifier)是一串128位的数字。GUIDs是COM识别事物的一种方法,且这种方法是与语言无关的。每个接口和COClass都有一个GUID。GUIDs是全球唯一的,所以这就避免了命名冲突问题(只要你使用COM API来创建它们)。你有时也会发现UUID(Universally Unique Identifier)这个术语。然而,UUIDs和GUIDs在实际用途方面是相同的。

Class ID或者是CLSID,它们都是用来命名COClass的GUID。Interface ID或者IID,它们是用来命名接口的GUID。

其实有两个原因使得GUIDs在COM中使用的如此广泛:

1.GUIDs仅仅是一串数字,任何语言都可以处理它们。
2.当任何人在任意机器上创建GUIDs的时候,它都是唯一的。因此,COM开发者们可以自己创建GUIDs,而且不用担心有两名开发者选择了相同的GUID。这就免除了需要一个中央权威机构发放GUIDs的要求。

COM用HRESULT这个类型(整型)来返回错误或者成功的代码。尽管有个'H'前缀,但它并不是指向什么东西的"句柄"。稍后我将会详细的说明HRESULTs以及怎样测试它们。

最后,在做COM相关的事务时,与你进行交互的COM库其实是操作系统的一部分。通常情况下,COM库就被成为COM,但在这里为了避免误解,我没有这样做。

使用COM对象

每种语言都有其处理对象的方法。例如,在C++中你可以在栈上创建它们,或者使用new操作符动态的分配它们。COM库提供了它自己的一套对象管理方法,使得COM是与语言无关的。比较一下COM和C++的对象管理,区别如下:

创建一个新对象

 在C++中,使用new操作符或直接在栈上创建对象。
 在COM中,需要调用COM库中的API。

删除对象

 在C++中,使用delete操作符或者让栈上的对象超出作用域,自动删除。
 在COM中,所有的对象必须维持它们自己的引用计数。调用者必须在使用完对象之后通知对象,COM对象会在引用计数为0的时候在内存中自动删除。

事实上在创建和删除两个阶段之间,你必须去使用它。在创建COM对象的时候,你要告诉COM需要什么样的接口,请求获取它。如果对象创建成功,COM库会返回一个指向所请求接口的指针。之后你就可以像使用C++对象指针一样,通过这个指针来调用方法了。

创建COM对象

为了要创建COM对象并从中获得一个接口,你可以调用COM库的API函数 CoCreateInstance()。它的原型如下:

HRESULT CoCreateInstance (
    REFCLSID  rclsid,
    LPUNKNOWN pUnkOuter,
    DWORD     dwClsContext,
    REFIID    riid,
    LPVOID
*   ppv );

形参如下:

rclsid
 COClass的CLSID。例如,你可以将CLSID_ShellLink传入创建一个COM对象用来建立快捷方式。
pUnkOuter
 这个参数只有在聚合(aggregate)COM对象的时候才使用。聚合COM对象可以在已经存在的COClass中加入新的方法。在这里,只需要传入NULL表明我们不需要使用聚合。
dwClsContext
 用来说明我们需要使用什么样的COM服务器。对这篇文章来说,我们总使用一个进程DLL作为最简单的服务器,因此传入CLSCTX_INPROC_SERVER。请注意,这里不应该使用CLSCTX_ALL(ATL的默认参数),因为它将在没有安装DCOM的Windows95系统上运行失败。
riid
 你所需要接口的IID,例如,你可以传入IID_IShellLink用来获取IShellLink接口的指针。
ppv
 接口指针的地址。COM库将通过这个参数返回所请求的接口。

当你调用CoCreateInstance()时,它将在注册表中查找CLSID,读取服务器的位置,并将服务器加载到内存中,最后创建一个你所申请的COClass实例。

下面是一个简单的调用,展示了一个CLSID_ShellLink对象并获取了COM对象的IShellLink接口指针。

HRESULT     hr;
IShellLink
* pISL;

hr 
= CoCreateInstance ( CLSID_ShellLink,         // CLSID of coclass
                        NULL,                    // not used - aggregation
                        CLSCTX_INPROC_SERVER,    // type of server
                        IID_IShellLink,          // IID of interface
                        (void**&pISL );        // Pointer to our interface pointer

    
if ( SUCCEEDED ( hr ) )
        
{
        
// Call methods using pISL here.
        }

    
else
        
{
        
// Couldn't create the COM object.  hr holds the error code.
        }

首先我们声明了一个用来接收CoCreateInstance()返回结果的HRESULT和一个IShellLink指针。之后调用CoCreateInstance()函数创建一个新的COM对象。如果hr包含成功的代码,则SUCCEEDED宏返回TRUE,否则返回FALSE。相应的,也有一个用来检测失败代码的FAILED宏。

(未完待续)

相关文章推荐

HTML5之SVG详解(一) 时间 2012-12-21 19:49:00 博客园-原创精华区 原文 http://www.cnblogs.com/hupeng/archive/2012/12/2

1、背景 SVG是Scalable Vector Graphics的缩写,意为可缩放矢量图形。1998年,万维网联盟成立了一个工作组,研发一种通过XML来表现矢量图形的技术——SVG!由于SVG...

iOS-NSRegularExpression(原创http://zhuhaibobb.blog.163.com/blog/static/27440067201411752450958/)

最近遇到一个需要进行字符串匹配的问题,我就想到用正则表达式来解决,通过ios中的NSRegularExpression这个类就可以帮助我们实现这个。 问题陈述: 现在我要对一个语句进行...

COM入门简介

COM简单来说在不同应用和语言之间提供了一种二进制代码级分享途径的方法。这和C++重用代码有很大不同,C++只是提供了一种源代码级的 代码重用(ATL就是一个很好的例子)它的调用者只能使用C++语言,...

COM编程入门(2)

原文地址:http://www.cppblog.com/mzty/archive/2005/12/23/2004.html   COM编程入门 第二部分 深入...

Com入门2

1. 实现COM组件的自注册和反注册 实现COM组件的自注册和反注册,本质上就是写注册表与删注册表。需要在DLL中引出两个函数:DllRegisterServer和DllUnregisterServ...

GCC使用简介 转自:http://blog.19lou.com/10061845/viewspace-384095

转自:http://blog.19lou.com/10061845/viewspace-384095 GCC是GNU项目的编译器组件之一,也是GNU最具有代表性的作品。在GCC设计之...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)