Using ATL with DirectX COM Interfaces

To use ATL with DirectX, you must redefine the interfaces for ATL compatibility. This will allow you to properly use the CComQIPtr class to obtain a pointer to an interface.

If you do not redefine the interfaces for ATL, you will get the following error message.

C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlbase.h(4704) :
  error C2787: 'IDirectXFileData' : no GUID has been associated with this object

The following code sample shows how to define the IDirectXFileData interface.

// Explicit declaration
struct __declspec(uuid("{3D82AB44-62DA-11CF-AB39-0020AF71E433}")) IDirectXFileData;

// Macro method
#define RT_IID(iid_, name_) struct __declspec(uuid(iid_)) name_
RT_IID("{1DD9E8DA-1C77-4D40-B0CF-98FEFDFF9512}", IDirectXFileData);

After redefining the interface, you must use the Attach method to attach the interface to the interface pointer returned by ::Direct3DCreate9. If you do not, the IDirect3D9 interface will not be properly released by the smart pointer class.

The CComPtr class internally calls IUnknown::AddRef on the interface pointer when the object is created and when an interface is assigned to the CComPtr class. To avoid leaking the interface pointer, do not call IUnknown::AddRef on the interface returned from ::Direct3DCreate9.

The following code properly releases the interface without doing IUnknown::AddRef.

CComPtr<IDirect3D9> d3d;
d3d.Attach(::Direct3DCreate9(D3D_SDK_VERSION));

Use the previous code. Do not use the following code, which calls IUnknown::AddRef followed by IUnknown::Release and does not release the reference added by ::Direct3DCreate9.

CComPtr<IDirect3D9> d3d = ::Direct3DCreate9(D3D_SDK_VERSION);

Note that this is the only place in Direct3D where you will have to use the Attach method in this manner.

For more information about the CComPTR and CComQIPtr classes, see their definitions in the Atlbase.h header file.