COM入门2(引用)

转载 2007年10月04日 11:33: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宏。

(未完待续)

 

相关文章推荐

COM编程入门(2)

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

Android studio value 2 (com.android.dex.DexException:资源重复引用或者加载问题)

因为使用Android studio 开发支付宝功能 遇到了很多开发异常情况 所以决定下功夫 总结一下 首先 Error:Execution failed for task ':app:de...

理解strong与weak)强引用与弱引用转载自《http://blog.sina.com.cn/s/blog_7c8dc2d50101lc08.html》

__weak 和 __strong 会出现在声明中 默认情况下,一个指针都会使用 __strong属性,表明这是一个强引用。这意味着,只要引用存在,对象就不能被销毁。这是一种所期望的行为:当所有(强...

COM与COM+从入门到精通.part2(pdf)

  • 2008年03月15日 11:50
  • 3.95MB
  • 下载

用ATL创建COM组件(详细分析了ATL创建的各种文件的意义,看完之后ATL就入门了)

转载自: http://www.cppblog.com/ice197983/articles/4178.html 其他不错的资源: http://technet.microsoft....

Com入门1

最近需要用到COM知识,总结一下刚学到的知识。 1. 什么是COM COM全称是Component Object Model,中文译为组件对象模型。COM组件在物理上是一些DLL或EXE文件;...
  • hhhbbb
  • hhhbbb
  • 2012年06月05日 09:51
  • 394

COM控件快速入门

 1.什么是COM COM是一种跨应用和语言共享二进制代码的方法。与C++不同,它提倡源代码重用。ATL便是一个很好的例证。源码级重用虽然好,但只能用于C++。它还带来了名字冲突的可能性,更不...

用FileZilla Server开FTP:看图入门(转自:http://blog.sina.com.cn/s/blog_46dac66f010003cm.html)

0. 关于续传和乱码的说明   问:听说FileZilla不能续传?答:那是以前,现在的新版可以了。   问:听说FileZilla处理中文文件有乱码。答:是有此现象,但这不是bug,原因见下...
  • lslxdx
  • lslxdx
  • 2011年09月29日 14:11
  • 1258

【TRIO-Basic从入门到精通教程八】QT使用Trio com组件编程实战

大家好,今天给大家带来一篇关于QT添加TRIO com组件的编程例程,给初次使用的朋友带来捷径之路。 首先,我们要使用TRIO COM组件,需要安装trio com组件程序。组件程序到官网下载最新版,...

COM编程入门(1)

原文地址:http://www.cppblog.com/mzty/archive/2005/12/23/2003.html   COM编程入门 第一部分 什么...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:COM入门2(引用)
举报原因:
原因补充:

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