COM对象聚合的原生态实现(非向导)

之前我有一篇博客是介绍如何使用ATL向导生成对象聚合的,那时候实现的快感掩盖了我无知的现实,现在重新拿起COM原理与应用这本书,我想还是全手工自己手写一遍吧,于

是就有了这篇博文,关于对象聚合,我想只是代码复用的一种,如果有两个接口ISome和IOther两个接口分别完成不同的功能,而那么对象聚合的含义就是在外部对象ISome中声

明所有的接口,但是在非ISome的功能函数中调用的是接口IOther的功能函数,而在对象聚合中则是通过变换接口实现的,即根据要使用的功能函数来QueryInterface相应的接口,

并且两者之间要能互相QueryInterface,仅此而已。在ATL中所有的接口都是继承的IDispatch接口,其实一般是没有必要的,我们不如使用midl,继承IUnknown来的简单,首先要

写的是idl文件,进行接口的编译。

import "oaidl.idl";
import "ocidl.idl";

[
	object,
	uuid(CB00819C-7DBF-4AA4-8AB7-3BBEC4944F18),
	dual,
	nonextensible,
	pointer_default(unique)
]
interface ISome : IUnknown{
	HRESULT some_function(byte* );
};
[
	object,
	uuid(FEB61B82-2B42-447A-B2D8-BC95C2386F01),
	dual,
	nonextensible,
	pointer_default(unique)
]
interface IOther : IUnknown{
        HRESULT other_function(byte*);
};
[
	uuid(18A12BCD-A164-490A-8ACA-43897D516FE3),
	version(1.0),
]
library objctLib
{
	importlib("stdole2.tlb");
	[
		uuid(80CC7337-3861-417E-B5E3-16D2AE98C645)		
	]
	coclass Some
	{
		[default] interface ISome;
	};
	[
		uuid(D09FE3C2-97B6-4366-83E7-4BA8E5B5E53D)		
	]
	coclass Other
	{
		[default] interface IOther;
	};
};

import "shobjidl.idl";

然后使用VS2010的工具midl进行编译的到5个文件*_i.c和*.h

在新建的控制台程序中加入*.h文件,之后在自行实现继承ISome和IOther的两个类,我的实现如下

#pragma once
#include
  
  
   
   
#include
   
   
    
    
#include"taste.h"

class AA:public ISome
{
public:
	AA(IUnknown* pOuter)
	{
		m_pOtherInterface=pOuter;
		m_Ref=0;
	}
	~AA(void){;}
protected:
	ULONG m_Ref;
public:
	IUnknown*m_pOtherInterface;
	HRESULT STDMETHODCALLTYPE QueryInterface( 
		/* [in] */ REFIID riid,
		/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) 
	{
		if(riid==IID_IOther)
		{
			return m_pOtherInterface->QueryInterface(riid,ppvObject);
		}
		else if(riid==IID_ISome)
		{
			*ppvObject=(IUnknown*)this;
			((IUnknown*)*ppvObject)->AddRef();

		}
		else if(riid==IID_IUnknown)
		{
			*ppvObject=(IUnknown*)this;
			((IUnknown*)*ppvObject)->AddRef();
		}
		else
			return E_NOINTERFACE;
		return S_OK;
	}
	ULONG STDMETHODCALLTYPE AddRef( void) 
	{
		return m_Ref++;
	}

	ULONG STDMETHODCALLTYPE Release( void) 
	{
		 m_Ref--;
		 if(m_Ref==0)
		 {
			 delete this;
		 }
		 return m_Ref;
	}
	HRESULT _stdcall some_function(byte*test)
	{
		MessageBoxA(NULL,(char*)test,"someFunction",0);
		return S_OK;
	}
	
};





class BB:public IOther
{
public:
	BB(void)
	{
		m_pSomeInterface=NULL;
		m_Ref=0;
	}
	~BB(void)
	{
		;
	}
protected:
	ULONG m_Ref;
	IUnknown* m_pSomeInterface;
public:
	ULONG _stdcall AddRef()
	{
		m_Ref++;
		return m_Ref;
	}
	ULONG  _stdcall Release()
	{
		 m_Ref--;

		 if(m_Ref==0)
		 {
			 m_pSomeInterface->Release();
			 delete this;
		 }
		 return m_Ref;
	}
	STDMETHODIMP other_function(byte*test)
	{
		::MessageBoxA(NULL,(char*)test,"otherFunction",0);
		return S_OK;		
	}
	HRESULT STDMETHODCALLTYPE QueryInterface( 
		/* [in] */ REFIID riid,
		/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject) 
	{
		if(riid==IID_IOther)
		{
			*ppvObject=(IUnknown*)this;
			((IUnknown*)*ppvObject)->AddRef();
		}
		else if(riid==IID_IUnknown)
		{
			*ppvObject=(IUnknown*)this;
			((IUnknown*)*ppvObject)->AddRef();
		}
		else if(riid==IID_ISome)
		{
			return m_pSomeInterface->QueryInterface(riid,ppvObject);
		}
		return S_OK;
	}	
	void Init()
	{
		//这里传递的应该是BB类的指针还是IOther接口的指针??????,值得思考下
		m_pSomeInterface=new AA(this);
		m_pSomeInterface->QueryInterface(IID_ISome,(void**)&m_pSomeInterface);
		下一步是获得BB中Other接口指针传递给AA,并将其记录下来,

	}
};


   
   
  
  

各位看官就不要说变量命名规范与否了哈,只是测试,这是客户端的调用

// 43121.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"hu.h"
#include"taste_i.c"
int _tmain(int argc, _TCHAR* argv[])
{
	BB hu;
	hu.Init();	
	ISome*ptr=NULL;
	HRESULT hr=hu.QueryInterface(IID_ISome,(void**)&ptr);
	ptr->some_function((byte*)"dsad");
	IOther* other=NULL;
	ptr->QueryInterface(IID_IOther,(void**)&other);
	other->other_function((byte*)"dasda");
	other->QueryInterface(IID_ISome,(void**)&ptr);
	ptr->QueryInterface(IID_IOther,(void**)&other);
	hu.Release();
}

现在看看其实也只不过是在创建类和被创建的类之间的指针的来回传递,创建类记被穿建的类的指针,同时将自己的this指针传递给被创建的类,同时这俩在QueryInterface进

行不断的变换。在生成的过程中,有时会遇到这样的问题 ,"不能实例化抽象基类",如果是这问题的话,你只需要瞧瞧,是不是有那个纯虚函数还没有实现,我一般问题就是在这儿。这就是即所谓的对象聚合吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世纪殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值