com_ptr<T>

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • CFG

    com_ptr<T>

    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_p tr<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::intrusiv e_ptr<T>. Seems good candidate. Just need to
    overload intrusive_ptr_a dd_ref and intrusive_ptr_r elease
    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






  • Gianni Mariani

    #2
    Re: com_ptr&lt;T&gt ;

    CFG wrote:[color=blue]
    > Is there a ready-to-use C++ smart pointer class working on top of COM
    > reference counting mechanism.[/color]

    Download Austria for free. The Austria C++ library provides a host of essential C++ tools including but generic factories, smart pointers, logging, unit testing framework and parameters/configuration system. The library will work with both Linux/GCC and win32/MVC++.


    It will support COM style pointers.
    [color=blue]
    >
    > Did anyone manage to tailor one of the available smart pointer libs to
    > handle COM objects?
    >
    > Probably I can use boost::shared_p tr<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::intrusiv e_ptr<T>. Seems good candidate. Just need to
    > overload intrusive_ptr_a dd_ref and intrusive_ptr_r elease
    > 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[/color]

    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;

    CoCreateInstanc e( ..., val.InnerRefere nce()

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

    Comment

    • John Harrison

      #3
      Re: com_ptr&lt;T&gt ;


      "CFG" <cf@fg.com> wrote in message news:1087422624 .800169@news.pu bnix.net...[color=blue]
      > 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?
      >[/color]

      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.

      Download Loki for free. A C++ library of designs, containing flexible implementations of common design patterns and idioms.


      john


      Comment

      • SenderX

        #4
        Re: com_ptr&lt;T&gt ;

        > So, can someone recommend good class to incapsulate COM reference
        counting?[color=blue]
        >
        > Level of portability: Windows C++ compilers: Borland, Intel C++, MSVC >=[/color]
        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;

        };


        Comment

        • John Harrison

          #5
          Re: com_ptr&lt;T&gt ;


          "SenderX" <xxx@xxx.com> wrote in message
          news:YUaAc.4917 8$eu.43733@attb i_s02...[color=blue][color=green]
          > > So, can someone recommend good class to incapsulate COM reference[/color]
          > counting?[color=green]
          > >
          > > Level of portability: Windows C++ compilers: Borland, Intel C++, MSVC >=[/color]
          > 6.x
          >
          >
          >
          > You can try this one I just whipped up:[/color]

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

          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


          Comment

          • SenderX

            #6
            Re: com_ptr&lt;T&gt ;

            > 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!.

            ;(


            Comment

            Working...