Ureader.com  
Microsoft software help and Community
   home   |   control panel login   |   archive   |  
 
Windos
win32.3rdparty
win32.directx.audio
win32.directx.ddk
win32.directx.graphics
win32.directx.input
win32.directx.managed
win32.directx.misc
win32.directx.networking
win32.directx.sdk
win32.directx.video
win32.dirx.grap.shaders
win32.gdi
win32.international
win32.kernel
win32.messaging
win32.mmedia
win32.networks
win32.ole
win32.rtc
win32.tapi
win32.tapi.beta
win32.tools
win32.ui
win32.wince
win32.wmi
windows.mediacenter
winfx.aero
winfx.announcements
winfx.avalon
winfx.collaboration
winfx.fundamentals
winfx.general
winfx.indigo
winfx.sdk
winfx.winfs
  
 
date: Fri, 25 Jul 2008 04:28:14 -0700 (PDT),    group: microsoft.public.win32.programmer.directx.video        back       


CComPtrEx   
I recently added an interface to one of the base classes and was
greeted by C2594 errors about ambigious conversions from  XXX * to
IUnknown*, This sort of thing can take hours to sort out, as you
refactor your objects to please the angry Gods of ATL.

This time I did a search on the compiler diagnostic code and
discovered an improved CComPtr that works even if there is more than
one CUnknown lurking within the composite. It comes from Jaredpar, who
also developed the useful SEH translation macro that has saved me
hours of troubleshooting time.

Here is a clone of this blog page in text form The narrator is
Jaredpar.

/* Another incredibly useful blog post from Jaredpar's weblog.

http://blogs.msdn.com/jaredpar/archive/2008/02/22/multiple-paths-to-iunknown.aspx

Multiple paths to IUnknown

ATL has a lot of great tools for COM programming and CComPtr
is a good example.  It's a smart pointer class which manages the
reference
count of an underlying COM object.

One of it's limitations though is it will only work properly
when the inheritance chain for a class has only one path to IUnknown.
If it has more than one path, the following error will be issued
when you attempt to assign a value of type T to the CComPtr.

error C2594: 'argument' : ambiguous conversions from
'SomeClass *' to 'IUnknown *'

The reason behind this is the operator= for CComPtr uses
AtlComPtrAssign to change the references.  The right hand
side of the assignment is passed to this function as IUnknown.
Since there are multiple paths to IUnknown the C++ compiler
cannot implicitly perform the cast and issues the above error.
I most frequently encounter this error in larger code bases
with older classes.  New functionality is needed so
I add a new interface and end up with a lot of
C2594 errors.


To work around this I defined a new CComPtr
class named CComPtrEx which inherits from CComPtr
base.  It defines the same operators as CComPtr but
uses a Copy Constructor and Swap to perform the = which
gets around the multiple paths to IUnknown.
The rest of the functions are identical to CComPtr.
*/


template <class T>
class CComPtrEx : public CComPtrBase<T>
{
public:
    CComPtrEx() throw()
    {
    }
    CComPtrEx(int nNull) throw() :
        CComPtrBase<T>(nNull)
    {
    }
    CComPtrEx(T* lp) throw() :
        CComPtrBase<T>(lp)
    {
    }
    CComPtrEx(_In_ const CComPtrEx<T>& lp) throw() :
        CComPtrBase<T>(lp.p)
    {
    }

    T* operator=(_In_opt_ T* lp) throw()
    {
        if(*this!=lp)
        {
            CComPtrEx<T> sp(lp);
            Swap(&p, &sp.p);
        }
        return *this;
    }

    T* operator=(_In_ const CComPtrEx<T>& lp) throw()
    {
        if(*this!=lp)
        {
            CComPtrEx<T> sp(lp);
            Swap(&p, &sp.p);
        }
        return *this;
    }
};
date: Fri, 25 Jul 2008 04:28:14 -0700 (PDT)   author:   Jamie Faye Fenton

Re: CComPtrEx   
From: "Jamie Faye Fenton"

> I recently added an interface to one of the base classes
> and was greeted by C2594 errors about ambigious
> conversions from  XXX * to IUnknown*, This sort of thing
> can take hours to sort out, as you refactor your objects
> to please the angry Gods of ATL.
[...]

class IA : public IUnknown;
class IB : public IUnknown;
class C : public IA, IB
{
  ...  IUnknown* p = (IUnknown*)(IA*)this; ...
}

Can't you just do the same in your code using CComPtr?


-- 
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm
date: Fri, 25 Jul 2008 16:24:27 -0400   author:   Alessandro Angeli

Google
 
Web ureader.com


    COPYRIGHT 2007, YARDI TECHNOLOGY LIMITED, ALL RIGHT RESERVE  |   contact us