现在的位置: 首页 > 综合 > 正文

在客户端使用智能指针的COM_自己弄个简单的智能指针

2013年09月16日 ⁄ 综合 ⁄ 共 5707字 ⁄ 字号 评论关闭

//dll / com 部分

//...........interface.h.........

#define INO    10
#define IANO   11
#define IBNO   12
//................
#define CANO            20
//...................

class I
{
public:
 virtual int AddRef()=0;
 virtual bool Release()=0;
 virtual bool QueryInterface (int I_ID, void **pOutInterface)=0;
};

class IA:public I
{
public:
 virtual void fna1(int i)=0;
 virtual void fna2(int i)=0;
 int m_ia;//¼ÓÁËËû¾Í²»·ûºÏcom¹æ·¶ÁË¡£¡£
};

class IB:public I
{
public:
 virtual void fnb1(int i)=0;
 virtual void fnb2(int i)=0;
};
//为了方便是用呢不得不让所有接口继承一个公共地接口 

 

// A.h: interface for the CA class.
//
//////////////////////////////////////////////////////////////////////
#pragma warning(disable: 4786)

#if !defined(AFX_A_H__BB099D15_A5F3_4E71_8760_1D2F67814BC4__INCLUDED_)
#define AFX_A_H__BB099D15_A5F3_4E71_8760_1D2F67814BC4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//..............................
#include "interface.h"
//#include "IUnknown.h"
#include <map>
#include <string>
using namespace std;
//................

class CA  :public IA,public IB//, public I //ûÀíÓɼÓÉϼ̳ÐI¾Í³öÏÖ´íÎó°¡¡£¡£
{
public:
 CA();
 virtual ~CA();
 virtual int AddRef();
 virtual bool Release();
 virtual bool QueryInterface( int I_ID, void **pOutInterface);
 virtual void fna1( int i );
 virtual void fna2(int i );
 virtual void fnb1( int i );
 virtual void fnb2(int i );
protected:
 int m_iRef;
 map<int , void*> m_map_iidtoi;
public:
 typedef map<int , void*>::value_type VTMAPIIDTOI;
 typedef map<int , void*>::iterator  ITMAPIIDTOI;
};

extern "C"
{
 __declspec(dllexport)  /*bool*/void  CreateInstance(int CLS_ID, int I_ID, //in
  void **ppi);//out
};
#endif // !defined(AFX_A_H__BB099D15_A5F3_4E71_8760_1D2F67814BC4__INCLUDED_)

 

// A.cpp: implementation of the CA class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "A.h"
#include <iostream>
using namespace std;

// TryCom3.cpp : Defines the entry point for the DLL application.

BOOL APIENTRY DllMain( HANDLE hModule,
       DWORD  ul_reason_for_call,
       LPVOID lpReserved
       )
{
    switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
 case DLL_THREAD_ATTACH:
 case DLL_THREAD_DETACH:
 case DLL_PROCESS_DETACH:
  break;
    }
    return TRUE;
}

// This is the constructor of a class that has been exported.
// see TryCom3.h for the class definition
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CA::CA()
{
 //this->m_iRef =1;
 this->m_map_iidtoi.insert( VTMAPIIDTOI(INO, static_cast<void*>( static_cast<I*>(static_cast<IA*>(this)) )) );
 this->m_map_iidtoi.insert( VTMAPIIDTOI(IANO,static_cast<IA*>(this)) );//×Ô¶¯»áת»»
 this->m_map_iidtoi.insert( VTMAPIIDTOI(IBNO,static_cast<IB*>(this)) );
}

CA::~CA()
{

}
int CA::AddRef()
{
 ++m_iRef;
 return m_iRef;
}

bool CA::Release()
{
 m_iRef -- ;
 if ( m_iRef == 0)
 {
  delete this;
 }
 return true;
}

bool CA::QueryInterface(int I_ID, void **pOutInterface)
{
 CA::ITMAPIIDTOI it=this->m_map_iidtoi.find(I_ID);
 if( it== this->m_map_iidtoi.end() )
 {
  *pOutInterface=NULL;
  return false;
 }
 *pOutInterface = (*it).second ;
 return true;
}
void CA::fna1( int i )
{
 cout<<"CA::IA::fna1  verison =2 "<<"input para: "<<i<<endl;
 
}
void CA::fna2(int i )
{
 cout<<"CA::IA::fna2  verison =2 "<<"input para: "<<i<<endl;
}
void CA::fnb1( int i )
{
 cout<<"CA::IA::fnb1  verison =2 "<<"input para: "<<i<<endl;
}
void CA::fnb2(int i )
{
 cout<<"CA::IA::fnb2  verison =2 "<<"input para: "<<i<<endl;
}

//////////////////////////
//bool
void  CreateInstance(int CLS_ID, int I_ID, //in
  void **ppi)//out
{
 if ( CLS_ID == CANO )
 {
  CA *p= new CA;
  p->QueryInterface( I_ID , ppi );
  if ( *ppi == NULL )
  {
   return ;//false;
  }
  return ;//true;/*Ö´Ðе½ÕâÀï°´F10³öÏÖÒ»¸ö´íÎó,ÌáʾÐÅϢΪ:
   //user breakpoint call from code at 0x7c921230 */
 }
 else
 {
  *ppi = NULL;
  return;// true;
 }
}

//客户端部分

 

// MyComPtr.h: interface for the CMyComPtr class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYCOMPTR_H__47F0A5E7_7474_4A9C_96A8_AA5E6A33FD37__INCLUDED_)
#define AFX_MYCOMPTR_H__47F0A5E7_7474_4A9C_96A8_AA5E6A33FD37__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

namespace nsmycomptr
{
template<class Type,int iid>
class CMyComPtr 
{
public:
 CMyComPtr()
 {
  this->m_pi = NULL;
 }
 CMyComPtr(Type *pi)
 {
  
  this->m_pi = pi;
  if( m_pi != NULL )
   m_pi->AddRef();
 }
 virtual ~CMyComPtr()
 {
  this->m_pi->Release();
  this->m_pi = NULL;
  //ÔںܶàÇé¿öÏÂÕâÑù»á³öÎÊÌâ,Ó¦¸ÃÔÚÕâÀïÃæµ÷ÓÃrelease
 }
 void Release()
 {
  if ( m_pi != NULL )
  {
   Type *pold= m_pi;
   m_pi=NULL;
   pold->Release();
  }
 }
 Type * operator->()
 {
  return m_pi;
 }
 operator Type*()
 {
  return m_pi;
 }
 Type ** operator&()
 {
  return &m_pi;
 }
protected:
 Type * m_pi;
};

/*接口转换模板函数 。。。。。*/

template<class DestIType,int Destiid>
DestIType *interface_cast(I * pi)
{
 DestIType *pdi=NULL ;
 pi->QueryInterface(Destiid , (void**)&pdi );
 return pdi;
}

};//end nsmycomptr
#endif // !defined(AFX_MYCOMPTR_H__47F0A5E7_7474_4A9C_96A8_AA5E6A33FD37__INCLUDED_)

//main............................

// UseTryCom3ByComPtr.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "../interface.h"
#include <iostream>

using namespace  std ;
#include "MyComPtr.h"
using namespace nsmycomptr;
#include "windows.h"
int main(int argc, char* argv[])
{
 HMODULE hm= ::LoadLibrary("E://lianxi//DLL_LIB_DCOM_COM//TryCom4_Óй²Í¬µÄ½Ó¿Ú»ùÀà//Debug//TryCom3.dll");
 if (hm == NULL)
 {
  cout<<"LoadLibrary error"<<endl;
  return 0;
 }
 
 typedef /*bool*/ void  (*pfnCreateInstance)(int , int , void **);
 pfnCreateInstance pfnci=(pfnCreateInstance)::GetProcAddress(hm,"CreateInstance");
 if (pfnci==NULL)
 {
  cout<<"get CreateInstance address error/n";
  return 0;
 }
 CMyComPtr<I,INO> iptr;
 pfnci( CANO , INO, (void **)&iptr );

 //IA *iap=interface_cast< IA, IANO>( iptr );
 //CMyComPtr<IA,IANO> iaptr(iap);
 CMyComPtr<IA,IANO> iaptr( interface_cast< IA, IANO>( iptr ) );
 iaptr->fna1(10 );
 iaptr->fna2(100);

 //IB *ibp=interface_cast<IB,IBNO>(iaptr);
 //CMyComPtr<IB,IBNO> ibptr(ibp);
 CMyComPtr<IB,IBNO> ibptr( interface_cast<IB,IBNO>(iaptr) );
 ibptr->fnb1(50);
 ibptr->fnb2(500);
 
// ::FreeLibrary(hm);
 return 0;
}
、、以上程序少了错误检测。。。

 

抱歉!评论已关闭.