COM组件应用(2)——IUnknown

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

2.组件API及接口指针中,除了IUnknown::AddRef()和IUnknown::Release()两个函数外,其它所有的函数,都以 HRESULT 作为返回值。

3.原则:COM 组件是运行在分布式环境中的通俗地说,你不能直接把一个内存指针直接作为参数传递给COM函数。

4.结果判断一般用VC提供的宏:

HRESULT hr = 调用组件函数;

if( SUCCEEDED( hr ) ){...} // 如果成功

if( FAILED( hr ) ){...} // 如果失败

5.Browser Helper Objects,我译为"浏览器帮助者对象",以下皆简称BHO


==================================

如果感觉不清楚,请先参看com组件应用(1),因为范例是从上例中改造过来的。


还是用具体范例来讲:computer_def.h

#include  < Unknwn.h >

#define  UUID_ICOMPUTER __declspec( uuid( "9DC95DDC-FF98-4afe-B17E-42F028E34F68" ) )
class  UUID_ICOMPUTER Icomputer:  public  IUnknown
{
public :
    
virtual   int  add( int  a,  int  b )  =   0 ;    
};


#define  UUID_ICOMPUTEREX __declspec( uuid( "3B8BF613-7AF1-4672-9EC3-E5DC49A6E8D9" ) )
class  UUID_ICOMPUTEREX IcomputerEx:  public  IUnknown
{
public :
    
virtual   int  sub( int  a,  int  b )  =   0 ;    
};

实现类:

class  Ccomputer : 
    
public  Icomputer,
    
public  IcomputerEx

{
public :
    
virtual  HRESULT STDMETHODCALLTYPE QueryInterface( 
        
/*  [in]  */  REFIID riid,
        
/*  [iid_is][out]  */   void  __RPC_FAR  * __RPC_FAR  * ppvObject)
    {
        
if (riid  ==  __uuidof(Icomputer))
        {
            
* ppvObject  =  (Icomputer * )( this );
        }

        
else   if (riid  ==  __uuidof(IcomputerEx))
        {
            
* ppvObject  =  (IcomputerEx * )( this );
        }

        
return  S_OK;
    }

    
virtual  ULONG STDMETHODCALLTYPE AddRef(  void )
    {
        m_nRef
++ ;
        
return  m_nRef;
    }

    
virtual  ULONG STDMETHODCALLTYPE Release(  void )
    {
        m_nRef
-- ;

        
if ( 0   ==  m_nRef)
        {
            delete 
this ;
        }

        
return   0 ;
    }

    
virtual   int  add( int  a,  int  b)
    {
        
return  a  +  b;
    }
    
virtual   int  sub( int  a,   int  b)
    {

        
return  a  -  b;
    }
private :
    ULONG m_nRef;

};

使用上:

Icomputer  * pComputer;

  IcomputerEx 
* pComputerEx;

  HMODULE hDll 
=  ::LoadLibrary(TEXT( " computer.dll " ));
  
  typedef HRESULT (__stdcall 
* PFN_DllGetClassObject)(Icomputer **  ppv);

  PFN_DllGetClassObject pDllGetClassObject 
=  (PFN_DllGetClassObject)::GetProcAddress(hDll,  " DllGetClassObject " );
  
  
if (NULL  ==  pDllGetClassObject)
  {
   
// nRet = STATUS_SEVERITY_ERROR;
  }

  
//  创建接口
  HRESULT hRet  =  pDllGetClassObject( & pComputer);
  
  
if (FAILED(hRet))
  {
   
// nRet = STATUS_SEVERITY_ERROR;
  }


……



 
int  iRet  =  pComputer -> add(iNum_1,iNum_2);
   
   pComputer
-> QueryInterface(__uuidof(IcomputerEx),( void ** ) & pComputerEx);

   
// pComputerEx = (pComputerEx)(pC);

   iRet 
=  pComputerEx -> sub(iNum_1,iNum_2);

 

阐述总结:继承IUnknown 接口,实现其中方法。 这样就可以通过QueryInterface 来查询接口,并使用其中的函数。

你可能感兴趣的:(浏览器,vc++)