COM学习(三)

来源:互联网 发布:淘宝3c认证怎么弄 编辑:程序博客网 时间:2024/06/07 06:45

文件名                   说明
math.h  math.cpp  COM实现文件
interface               COM接口文件
simple.cpp            客户文件

//****************************************************
//****************COM 定义
//*************math.h***********************
#i nclude "interface.h"

class CMath : public ISimpleMath, //继承接口
     public IAdvancedMath
{
private:
 ULONG m_cRef; //引用计数

private:
 int calcFactorial(int nOp);
 int calcFabonacci(int nOp);

public:
 CMath(); //构造函数
 //IUnknown Method:必备的3个COM自身管理函数
 STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
 STDMETHOD_(ULONG, AddRef)();
 STDMETHOD_(ULONG, Release)();

 // ISimpleMath Method
 int Add(int nOp1, int nOp2);
 int Subtract(int nOp1, int nOp2);
 int Multiply(int nOp1, int nOp2);
 int Divide(int nOp1, int nOp2);

 // IAdvancedMath Method
 int Factorial(int nOp);
 int Fabonacci(int nOp);
};

//*************math.cpp****************************************************
//COM 实现
#i nclude "interface.h"
#i nclude "math.h"

STDMETHODIMP CMath::QueryInterface(REFIID riid, void **ppv)
{// 这里这是实现dynamic_cast的功能,但由于dynamic_cast与编译器相关。
 if(riid == IID_ISimpleMath)
  *ppv = static_cast<ISimpleMath *>(this);
 else if(riid == IID_IAdvancedMath)
  *ppv = static_cast<IAdvancedMath *>(this);
 else if(riid == IID_IUnknown) //COM接口(入口)
  *ppv = static_cast<ISimpleMath *>(this);
 else { //没有找到该接口
  *ppv = 0;
  return E_NOINTERFACE;
 }

 reinterpret_cast<IUnknown *>(*ppv)->AddRef(); //这里要这样是因为引用计数是针对组件的
 return S_OK;
}

STDMETHODIMP_(ULONG) CMath::AddRef()
{
 return ++m_cRef;
}

STDMETHODIMP_(ULONG) CMath::Release()
{
 ULONG res = --m_cRef; // 使用临时变量把修改后的引用计数值缓存起来
 if(res == 0)   // 因为在对象已经销毁后再引用这个对象的数据将是非法的
  delete this;
 return res;
}

int CMath::Add(int nOp1, int nOp2)
{
 return nOp1+nOp2;
}

int CMath::Subtract(int nOp1, int nOp2)
{
 return nOp1 - nOp2;
}

int CMath::Multiply(int nOp1, int nOp2)
{
 return nOp1 * nOp2;
}

int CMath::Divide(int nOp1, int nOp2)
{
 return nOp1 / nOp2;
}

int CMath::calcFactorial(int nOp)
{
 if(nOp <= 1)
  return 1;

 return nOp * calcFactorial(nOp - 1);
}

int CMath::Factorial(int nOp)
{
 return calcFactorial(nOp);
}

int CMath::calcFabonacci(int nOp)
{
 if(nOp <= 1)
  return 1;

 return calcFabonacci(nOp - 1) + calcFabonacci(nOp - 2);
}

int CMath::Fabonacci(int nOp)
{
 return calcFabonacci(nOp);
}


CMath::CMath()
{
 m_cRef=0;
}

//*********************************//接口界面
//***********************interface.h*************************** 

#ifndef INTERFACE_H
#define INTERFACE_H
#i nclude <unknwn.h>

//{7C8027EA-A4ED-467c-B17E-1B51CE74AF57}
static const GUID IID_ISimpleMath =
{ 0x7c8027ea, 0xa4ed, 0x467c, { 0xb1, 0x7e, 0x1b, 0x51, 0xce, 0x74, 0xaf, 0x57 } };

//{CA3B37EA-E44A-49b8-9729-6E9222CAE84F}
static const GUID IID_IAdvancedMath =
{ 0xca3b37ea, 0xe44a, 0x49b8, { 0x97, 0x29, 0x6e, 0x92, 0x22, 0xca, 0xe8, 0x4f } };

interface ISimpleMath : public IUnknown
{
public:
 virtual int Add(int nOp1, int nOp2) = 0;  
 virtual int Subtract(int nOp1, int nOp2) = 0;
 virtual int Multiply(int nOp1, int nOp2) = 0;
 virtual int Divide(int nOp1, int nOp2) = 0;
};

interface IAdvancedMath : public IUnknown
{
public:
 virtual int Factorial(int nOp1) = 0;
 virtual int Fabonacci(int nOp1) = 0;
};
#endif

//*******************************************COM 客户端
#i nclude "math.h"
#i nclude <iostream>

using namespace std;


int main(int argc, char* argv[])
{
 ISimpleMath *pSimpleMath = NULL;  // 声明接口指针
 IAdvancedMath *pAdvMath = NULL;
 CMath *pMath = new CMath;  // 创建对象实例,我们暂时这样创建对象实例,COM有创建对象实例的机制
 HRESULT hr;  //COM的返回值
 hr=pMath->QueryInterface(IID_ISimpleMath, (void **)&pSimpleMath); // 查询对象实现的接口ISimpleMath
 if(pSimpleMath)
  cout << "10 + 4 = " << pSimpleMath->Add(10, 4) << endl;
 pSimpleMath->QueryInterface(IID_IAdvancedMath, (void **)&pAdvMath); // 查询对象实现的接口IAdvancedMath
 if(pAdvMath)
  cout << "10 Fabonacci is " << pAdvMath->Fabonacci(10) << endl; 

 pAdvMath->Release();
 pSimpleMath->Release();
 return 0;
}

原创粉丝点击