COM组件应用(2)——IUnknown

本文详细介绍了COM组件的设计原理及其实现过程。首先讲解了IUnknown接口中的QueryInterface、AddRef、Release三个核心函数的作用,随后通过具体示例展示了如何定义和实现COM接口,包括接口查询、引用计数管理等关键步骤。

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 来查询接口,并使用其中的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值