在很久以前,就因为项目的需求,接触到了组件的概念,但是由于各种原因(主要还是自己太懒...)没有系统的学习和理解组件.进几天项目空闲下来,我魔兽世界也85..所以安心的把组件的知识梳理一遍,当然只是很基础很基础的东西,里面还参杂了一些自己的理解,写下来,可以让自己以后复习,也希望高手能指点,我的主要参考资料是《com技术内幕》,csdn上有下载。

什么是com组件?什么是com技术?这些有许多解释,我个人的理解就是控件咯,类咯,dll咯,总之就是个黑盒子,我不知道它是用啥实现的,只要给我接口,知道咋用就行了——这就是我理解的组件。

那么如何实现组件呢?我们可以用c++的虚类来理解接口.每个接口实现了许多函数,许多接口便组成了组件...bulabulabula

所有的com接口都实现了IUnknown接口(接口中的函数都必须实现,java中是这样),该接口有三个方法:QueryInterfaceAddRefReleasecom接口的前三个函数必定是这三个,下面介绍这三个函数的功能

QueryInterfaceconst IID&iidvoid**ppv):客户用来通过此函数来查询某个组件是否支持某个特定的接口,若支持则返回指向此接口的指针,否则返回错误代码;第一个参数表示“接口标识符”,标示接口所需的常量,另一个参数存放接口地址的指针;返回HRESULT可用相应的宏判断返回值的意义;当接口不被支持的时候*ppv应该为NULL,下面是一些代码和注释...

#include <iostream>

#include <objbase.h>

using namespace std;

void trace(const char* msg) { cout << msg << endl ;}





// Interfaces

interface IX : IUnknown

{

virtual void __stdcall Fx() = 0 ;

} ;



interface IY : IUnknown

{

virtual void __stdcall Fy() = 0 ;

} ;



interface IZ : IUnknown

{

virtual void __stdcall Fz() = 0 ;

} ;



// Forward references for GUIDs

extern const IID IID_IX ;

extern const IID IID_IY ;

extern const IID IID_IZ ;



//

// Component

//

class CA : public IX,

           public IY

{

//IUnknown implementation

virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;

virtual ULONG __stdcall AddRef() { return 0 ;}

virtual ULONG __stdcall Release() { return 0 ;}



// Interface IX implementation

virtual void __stdcall Fx() { cout << "Fx" << endl ;}



// Interface IY implementation

virtual void __stdcall Fy() { cout << "Fy" << endl ;}

} ;



HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)/*存ä?放¤?地Ì?址¡¤的Ì?指?针?void* 可¨¦以°?包㨹容¨Y任¨?意°a类¤¨¤型¨ª*/

{ 

if (iid == IID_IUnknown)

{



trace("QueryInterface: Return pointer to IUnknown.") ;

/*

static_cast < type-id > ( expression )

 ? ?该?运?算?符¤?把ã?expression转Áa换?为atype-id类¤¨¤型¨ª,ê?但Ì?没?有®D运?行D时º¡À类¤¨¤型¨ª检¨¬查¨¦来¤¡ä保À¡ê证¡è转Áa换?的Ì?安ã2全¨?性?。¡ê它¨¹主¡Â要°a有®D如¨?下?几?种?用®?法¤¡§:êo

   ? ?①騴用®?于®¨²类¤¨¤层?次ä?结¨¢构1中D基¨´类¤¨¤(ꡧ父?类¤¨¤)ê?和¨ª派¨¦生¦¨²类¤¨¤(ꡧ子Á¨®类¤¨¤)ê?之?间?指?针?或¨°引°y用®?的Ì?转Áa换?。¡ê

 ? ?进?行D上¦?行D转Áa换?(ꡧ把ã?派¨¦生¦¨²类¤¨¤的Ì?指?针?或¨°引°y用®?转Áa换?成¨¦基¨´类¤¨¤表À¨ª示º?)ê?是º?安ã2全¨?的Ì?;ê?

   ? ?进?行D下?行D转Áa换?(ꡧ把ã?基¨´类¤¨¤指?针?或¨°引°y用®?转Áa换?成¨¦派¨¦生¦¨²类¤¨¤表À¨ª示º?)ê?时º¡À,ê?由®¨¦于®¨²没?有®D动¡¥态¬?类¤¨¤型¨ª检¨¬查¨¦,ê?所¨´以°?是º?不?安ã2全¨?的Ì?。¡ê

 ? ?②騲用®?于®¨²基¨´本À?数ºy据Y类¤¨¤型¨ª之?间?的Ì?转Áa换?,ê?如¨?把ã?int转Áa换?成¨¦char,ê?把ã?int转Áa换?成¨¦enum。¡ê这a种?转Áa换?的Ì?安ã2全¨?性?也°2要°a开a发¤¡é人¨?员¡À来¤¡ä保À¡ê证¡è。¡ê

   ? ?③é?把ã?空?指?针?转Áa换?成¨¦目?标À¨º类¤¨¤型¨ª的Ì?空?指?针?。¡ê

 ? ?④騹把ã?任¨?何?类¤¨¤型¨ª的Ì?表À¨ª达ä?式º?转Áa换?成¨¦void类¤¨¤型¨ª。¡ê

   ?注Á¡é意°a:êostatic_cast不?能¨¹转Áa换?掉Ì?expression的Ì?const、¡évolitale、¡é或¨°者?__unaligned属º?性?。¡ê

*/



*ppv = static_cast<IX*>(this) ;//*ppv放¤?的Ì?是º?地Ì?址¡¤...

}

else if (iid == IID_IX)

{

trace("QueryInterface: Return pointer to IX.") ;

*ppv = static_cast<IX*>(this) ;

}

else if (iid == IID_IY)

{

trace("QueryInterface: Return pointer to IY.") ;

*ppv = static_cast<IY*>(this) ;

}

else

{  	   

trace("QueryInterface: Interface not supported.") ;

*ppv = NULL ;

return E_NOINTERFACE ;

}

reinterpret_cast<IUnknown*>(*ppv)->AddRef() ; // See Chapter 4.

return S_OK ;

}



//

// Creation function

//

IUnknown* CreateInstance()

{

IUnknown* pI = static_cast<IX*>(new CA) ;

pI->AddRef() ;

return pI ;

}



//

// IIDs

//

// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IX = 

{0x32bb8320, 0xb41b, 0x11cf,

{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;



// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IY = 

{0x32bb8321, 0xb41b, 0x11cf,

{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;



// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IZ = 

{0x32bb8322, 0xb41b, 0x11cf,

{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;



//

// Client

//

int main()

{

HRESULT hr ;



trace("Client:         Get an IUnknown pointer.") ;

IUnknown* pIUnknown = CreateInstance() ;



   

trace("Client:         Get interface IX.") ;



IX* pIX = NULL ; 

hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX) ;

if (SUCCEEDED(hr))

{

trace("Client:         Succeeded getting IX.") ;

pIX->Fx() ;          // Use interface IX.

}





trace("Client:         Get interface IY.") ;



IY* pIY = NULL ;

hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY) ;

if (SUCCEEDED(hr))

{

trace("Client:         Succeeded getting IY.") ;

pIY->Fy() ;          // Use interface IY.

}





trace("Client:         Ask for an unsupported interface.") ;



IZ* pIZ = NULL ;

hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ) ;

if (SUCCEEDED(hr))

{

trace("Client:         Succeeded in getting interface IZ.") ;

pIZ->Fz() ;

}

else

{

trace("Client:         Could not get interface IZ.") ;

}





trace("Client:         Get interface IY from interface IX.") ;



IY* pIYfromIX = NULL ;

hr = pIX->QueryInterface(IID_IY, (void**)&pIYfromIX) ;

if (SUCCEEDED(hr))

{

trace("Client:         Succeeded getting IY.") ;

pIYfromIX->Fy() ;

}





trace("Client:         Get interface IUnknown from IY.") ;



IUnknown* pIUnknownFromIY = NULL ;

hr = pIY->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromIY) ;

if (SUCCEEDED(hr))

{

cout << "Are the IUnknown pointers equal?  " ;

if (pIUnknownFromIY == pIUnknown)

{

cout << "Yes, pIUnknownFromIY == pIUnknown." << endl ;

}

else

{

cout << "No, pIUnknownFromIY != pIUnknown." << endl ;

}

}



// Delete the component.

delete pIUnknown ;



return 0 ;

}

posted on 2011-07-17 14:37  筋肉强打  阅读(447)  评论(0编辑  收藏  举报