ATL实战开发指南---2.2

下面代码演示多接口的概念

class IMath
{
public : 
    virtual int Add(int a, int b) = 0;
    virtual int Subtract(int a, int b) = 0;
    virtual int Divide(int a, int b) = 0;
    virtual int Multify(int a, int b) = 0;
}

class IAdvancedMath
{
public : 
    virtual int Factorial (int16_t n) = 0;
    virtual int Fibonacci (int16_t n) = 0;
};

如果你要打算改变你的接口:在接口中添加 新的方法,或者改变接口中已有方法的参数。这样是不应该的,因为客户程序在编译的时候已经同接口的虚表绑定了,比如上面的IAdvancedMath。所以这里建议你再添加一个新的接口 :IAdvancedMathEx. 像下面这样

class IAdvancedMathEx : public IAdvancedMath
{
      virtual int Circle(int radius) = 0;
}


那么上面我们描述了COM的接口的原理,具体的实现的细节等一下再讲,那么对于使用组件的客户端怎么来访问呢?

IMath* pIMath;
CoCreateInstance(CLSID_MATH, NULL, CLSCTX_INPROC, IID_IMATH, &pIMath);


这里有很多细节问题,但是最重要的,COM在这里创建了一个实例, 并返回了一个指向vtable结构指针的指针。该table结构是由抽象类IMath描述的。所以我们可以调用这个抽象类暴露出的方法。

大多数组件都有多个接口,系统将使用某种机制来实现,使客户可以访问某个特定的接口。

 

标准COM接口的一些细节

1.所有组件必须实现IUnknown接口,提供了一种标准途径,使用户可以在指定的组件访问某个特定的接口---这就是上文提到的COM的某种标准。组件对象的生存期管理

下面这是它的接口原型:

class IUnknow
{
virtual HRESULT STDMETHODCALLTYPE QueryInterface( 
                /* [in] */ REFIID riid,
                /* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) = 0;

            virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0;

            virtual ULONG STDMETHODCALLTYPE Release( void) = 0;
};

当客户需要使用组件提供的服务的时候,可以通过接口查询或者组件实例化的时候得到接口指针。

HRESULT STDMETHODCALLTYPE Math::QueryInterface( 
	/* [in] */ REFIID riid,
	/* [annotation][iid_is][out] */ 
	__RPC__deref_out  void **ppvObject)
{
	if (IID_IMATH == riid)
	{
		*ppvObject = static_cast<IMath*>(this);
	}
	else if (IID_IADVANCEDMATH == riid)
	{
		*ppvObject = static_cast<IAdvancedMath*>(this);
	}
	else if (IID_IUnknown == riid)
	{
		*ppvObject = static_cast<IMath*>(this);
		//or *ppvObject = static_cast<IAdvancedMath*>(this);
	}
	else
	{
		return E_FAIL;
	}
	static_cast<IUnknown*>(*ppvObject)->AddRef();

	return S_OK;
}


 

在queryinterface的一个实现中,我们可以看到它完整的实现了我们对该接口定位的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值