comptr.h

来自「symbian 下的helix player源代码」· C头文件 代码 · 共 281 行

H
281
字号
////////////////////////////////////////
//
// interface for a simple wrapper class for COM (ref counted) pointers.
//

#if !defined(COM_PTR_INC__)
#define COM_PTR_INC__

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

#include "hxassert.h"

namespace comptr_util
{
template<typename I>	
inline
void Release(I*& p)
{
    if( p )
    {
        p->Release();
        p = 0;
    }
}

#if defined(HELIX_FEATURE_FULLGUID)
typedef REFIID IID_RETTYPE;
#else
// IID is an enum and a reference to it cannot be returned, so we force return by value
typedef IID IID_RETTYPE;
#endif

// trait for allowing us to get REFIID corresponding to IID
template<typename I>
struct IIDTraits
{
    // missing #include "comptr_traits.h"? missing trait in "comptr_traits.h"?
    static inline IID_RETTYPE riid() { return missing_trait_definition; }
};

/*
template <class T>
struct ptr_traits
{
  typedef void ptr_type; // 'void' for non-pointers
};

// partial-specialization for ptrs
template <class T>
struct ptr_traits<T*>
{
  typedef T ptr_type;
};

// convert from IUnknown* to IPtr via QI
template<typename IPtr, typename IOther>
inline
IPtr com_cast(IOther* pOther)
{
    IPtr ptr = 0;
    if(pOther)
    {
        typename ptr_traits<IPtr>::ptr_type I;
        pOther->QueryInterface(comptr_util::IIDTraits<I>::riid(), reinterpret_cast<void**>(&ptr));
    }
    return ptr;
}
*/
} // ns comptr_util


template<typename I>
class comptr 
{
public:

    // construction
    comptr(I* p = 0);
    //comptr(IUnknown* pOther);
    comptr(const comptr<I>& rhs);
    
    // destruction
    ~comptr();

    // assignment
    comptr<I>& operator= (I* p);
    comptr<I>& operator= (const comptr<I>& rhs);
    
    // take refcount (don't increment)
    void Take(I* p);

    // query interface
    bool From(IUnknown* pOther); 

    // conversion
    // I* Ptr() const;
    operator I*() const;

    // operators
    // operator bool() const { return m_p != 0; }
    I* operator-> () const;
    

    // methods
    void Reset(I* p = 0);
    I*& AsRef();
    void** AsPtrPtr();

private:
    I* m_p;

};


template< typename I>
inline
comptr<I>::comptr (I* p)
: m_p(p)
{
    if(m_p)
    {
        m_p->AddRef();
    }
}


template<typename I>
inline
comptr<I>::comptr(const comptr<I>& rhs)
: m_p(rhs.m_p) 
{
    if( m_p )
    {
	m_p->AddRef();
    }
}


template <typename I>
/*inline*/
void comptr<I>::Reset(I* p)
{
    if( m_p != p)
    {
	// relinquish m_p
	if( m_p )
	{
	    m_p->Release();
	}

	// aquire p
	m_p = p;
	if( m_p )
	{
	    m_p->AddRef();
	}
    }
	
}


template<typename I>
inline
comptr<I>::~comptr()
{
    comptr_util::Release(m_p);
}


template< typename I>
inline
comptr<I>& comptr<I>::operator= (const comptr<I>& rhs)
{
    Reset(rhs.m_p);
    return *this;
}

template< typename I>
inline
comptr<I>& comptr<I>::operator= (I* p)
{
    Reset(p);
    return *this;
}

/*
template <typename I>
inline
I* comptr<I>::Ptr() const
{
    return m_p;
}*/

template <typename I>
inline
comptr<I>::operator I*() const
{
    return m_p;
}

template <typename I>
inline
I* comptr<I>::operator->() const
{
    HX_ASSERT_VALID_PTR(m_p);
    return m_p;
}

//
// Take addref'd pointer; for cases where interface 
// is already addref'd for you:
//
// comptr<ISomething> something;
// /* GetIface() returns addref'd ptr */
// something.Take(pOther->GetIface()); 
//
template<typename I>
inline
void comptr<I>::Take(I* p)
{
    comptr_util::Release(m_p);
    m_p = p; // already has ref count incremented
}


//
// enables us to write:
//
// comptr<IMyInterface> iface;
// /* pOther may expose IMyInterface */
// if(iface.From(pOther))
// { /* use it ... */ }
//
template< typename I>
inline
bool comptr<I>::From( IUnknown* pOther )
{
    comptr_util::Release(m_p);
    if(pOther)
    {
        pOther->QueryInterface(comptr_util::IIDTraits<I>::riid(), reinterpret_cast<void**>(&m_p));
    }
    //m_p = comptr_util::com_cast<I*>(pOther);
    return m_p != 0;
}




//
// For passing to functions expecting I*& for write access to I*
//
// HX_RESULT Factory::GetMyInterface(IMyInterface*& pInterfaceOut); 
//
// comptr<IMyInterface> iface;
// pFactory->GetMyInterface(iface.AsRef());
//
template <typename I>
inline
I*& comptr<I>::AsRef() 
{ 
    HX_ASSERT(!m_p); // about to overwrite and un-released ptr? (must be null)
    return m_p; 
} 

//
// For passing to functions expecting void** for write access to I*
//
template <typename I>
inline
void** comptr<I>::AsPtrPtr()
{
    HX_ASSERT(!m_p); // about to overwrite and un-released ptr? (must be null)
    return reinterpret_cast<void**>(&m_p);
}


#endif // !defined(COM_PTR_INC__)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?