com_ptr<T>

C

CFG

Is there a ready-to-use C++ smart pointer class working on top of COM
reference counting mechanism.

Did anyone manage to tailor one of the available smart pointer libs to
handle COM objects?

Probably I can use boost::shared_ptr<T> with custom deleter -
which calls obj->Release() instead of delete obj;
But this workaround is not safe and wasteful (we have two separate
reference counters around: first counter is an internal COM's one, and
second counter is shared_ptr's one)

I had a look at boost::intrusive_ptr<T>. Seems good candidate. Just need to
overload intrusive_ptr_add_ref and intrusive_ptr_release
The other issue with intrusive_ptr is that by default its constructor calls
AddRef which is undesirable.

So, can someone recommend good class to incapsulate COM reference counting?

Level of portability: Windows C++ compilers: Borland, Intel C++, MSVC >= 6.x
 
G

Gianni Mariani

CFG said:
Is there a ready-to-use C++ smart pointer class working on top of COM
reference counting mechanism.

http://austria.sourceforge.net/

It will support COM style pointers.
Did anyone manage to tailor one of the available smart pointer libs to
handle COM objects?

Probably I can use boost::shared_ptr<T> with custom deleter -
which calls obj->Release() instead of delete obj;
But this workaround is not safe and wasteful (we have two separate
reference counters around: first counter is an internal COM's one, and
second counter is shared_ptr's one)

I had a look at boost::intrusive_ptr<T>. Seems good candidate. Just need to
overload intrusive_ptr_add_ref and intrusive_ptr_release
The other issue with intrusive_ptr is that by default its constructor calls
AddRef which is undesirable.

So, can someone recommend good class to incapsulate COM reference counting?

Level of portability: Windows C++ compilers: Borland, Intel C++, MSVC >= 6.x

I don't know if MSCV6 will work. MSCV7 should work fine.

I recently made a change to support non COM style pointers (new objects
start with a reference count of 0 instead of 1).

Usage:

Ptr< IUnknown *, COMPtrTraits > val;

CoCreateInstance( ..., val.InnerReference()

I attempted to automatically choose between COMPtrTraits and PtrTraits
by using some heuristic by alas compilers have too many bugs to get that
right ...
 
J

John Harrison

CFG said:
Is there a ready-to-use C++ smart pointer class working on top of COM
reference counting mechanism.

Did anyone manage to tailor one of the available smart pointer libs to
handle COM objects?

Loki has a highly customisable smart pointer. I think they have a COM
version already but would be easy to add if they don't.

http://sourceforge.net/projects/loki-lib/

john
 
S

SenderX

So, can someone recommend good class to incapsulate COM reference
counting?
Level of portability: Windows C++ compilers: Borland, Intel C++, MSVC >=
6.x



You can try this one I just whipped up:

template< typename T >
struct obj_ptr_convert
{
T *m_pPtr;

explicit obj_ptr_convert( T *pPtr ) : m_pPtr( pPtr ) {}

};


// Type T has to have public AddRef && Release functions...
template< typename T >
class obj_ptr
{

public:

typedef obj_addref< obj_ptr& > t_AddRef;


public:

explicit obj_ptr( T *pPtr = 0 ) : m_pPtr( pPtr )
{
AddRef();
}

obj_ptr( const obj_ptr &Src ) : m_pPtr( Src.m_pPtr )
{
AddRef();
}


#ifndef _MSC_VER
template< typename T1 >
obj_ptr( const obj_ptr< T1 > &Src ) : m_pPtr( Src.m_pPtr )
{
AddRef();
}
#endif


~obj_ptr()
{
Release();
}


public:

inline T* Get() const
{
return m_pPtr;
}

inline void Set( T *pPtr )
{
Release();
m_pPtr = pPtr;
}


public:

inline T* operator ->() { return Get(); };


public:

inline obj_ptr& operator =( T *pPtr )
{
Release();
m_pPtr = pPtr;
AddRef();
return *this;
}

inline obj_ptr& operator =( const obj_ptr &Src )
{
Release();
m_pPtr = Src.m_pPtr;
AddRef();
return *this;
}


#ifndef _MSC_VER
template< typename T1 >
inline obj_ptr& operator =( const obj_ptr< T1 > &Src )
{
Release();
m_pPtr = Src.m_pPtr;
AddRef();
return *this;
}
#endif


public:

inline obj_ptr& operator =( const obj_ptr_convert< T > &Ref )
{
Release();
m_pPtr = Ref.m_pPtr;
AddRef();
return *this;
}

template< typename T1 >
inline operator obj_ptr_convert< T1 >()
{
return obj_ptr_convert< T1 >( m_pPtr );
}

template< typename T1 >
inline operator obj_ptr< T1 >()
{
return obj_ptr< T1 >( m_pPtr );
}


private:

inline void AddRef() const
{
if ( m_pPtr )
{
m_pPtr->AddRef();
}
}

inline void Release()
{
if ( m_pPtr )
{
m_pPtr->Release();
m_pPtr = 0;
}
}


private:

T *m_pPtr;

};
 
J

John Harrison

SenderX said:
6.x



You can try this one I just whipped up:

It's bugged, you've ignored the possibility of self assignment.
inline obj_ptr& operator =( const obj_ptr &Src )
{
Release();
m_pPtr = Src.m_pPtr;
AddRef();
return *this;
}

inline obj_ptr& operator =( const obj_ptr &Src )
{
Src.AddRef();
Release();
m_pPtr = Src.m_pPtr;
return *this;
}

Maybe you have a similar error in other places as well

john
 
S

SenderX

Maybe you have a similar error in other places as well

DOH... Thank you!

I totally forgot about this fact when I was editing this for the OP. This
template was special case for objects produced by a proxy gc.

I forgot to snip some stuff. Like:

typedef obj_addref< obj_ptr& > t_AddRef;

And some other CPU specific code and some inline asm, relevant to
self-assignment. The proxy gc is a C API, and needs some special case
wrappers.

When I say "whipped up", I should have said snipped the hell out of a c++
template wrapping a not so C++ friendly C API. Sorry!.

;(
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,170
Messages
2,570,925
Members
47,468
Latest member
Fannie44U3

Latest Threads

Top