NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Custom COM Callable Wrappers (CCCWs)

This section discusses customized COM callable wrappers (CCCWs), which handle calls made from unmanaged to managed code.

The CCCW class is typically used to proxy the calls from unmanaged to managed code. The wrapper class is a reference counted class that implements an unmanaged interface and typically caches a reference to a managed interface. As calls are made on the unmanaged interface, the wrapper handles the call by delegating the call cached, managed interface.

For example, consider the OldToNewWrapper shown below. This wrapper implements the unmanaged interface IOld and delegates the calls to the managed interface INew.

In Wrappers.h
class OldToNewWrapper : public IOld {
public:
   OldToNewWrapper (INew *pNew);
   ~OldToNewWrapper();

   ULONG __stdcall AddRef(void);
   ULONG __stdcall Release(void);
   HRESULT __stdcall QueryInterface(REFIID riid, void **ppv);
   HRESULT __stdcall OldMethod(void);

private:
   ULONG m_cRef;
   INew *m_pINew;
};

In Wrappers.cpp
OldToNewWrapper::OldToNewWrapper (INew *pNew) {
   m_pINew = pNew;
   m_cRef = 1;
}

ULONG OldToNewWrapper::AddRef(void) {
   return ++m_cRef;
}

ULONG OldToNewWrapper::Release(void) {
   if (--m_cRef != 0)
         return m_cRef;
   
   delete this;   
   return 0;
}

HRESULT OldToNewWrapper::QueryInterface(REFIID riid, void **ppv) {
   if (riid == IID_IOld) 
      *ppv = (IOld *)this;
   else 
   {
      *ppv = NULL;
      return E_NOINTERFACE;
   }

   AddRef();
   return S_OK;
}

HRESULT OldToNewWrapper::OldMethod() {
try {
      m_pINew->NewMethod();
catch (Exception *e) {
   return E_FAIL;
}

   return S_OK;
}

In the code shown here, the wrapper’s implementation of OldMethod directly calls NewMethod on the cached INew interface. The wrapper could provide an alterative implementation of the OldMethod.

Note: The code above shows m_pINew as a member of the OldToNewWrapper class. Currently implementations of the MC++ compiler do not allow unmanaged types (like OldToNewWrapper) to contain references to managed types. To get around this issue, the reference to the managed type should be stored in a static member of a global class. For example:

__gc class Globals {
   public:
      static INew *m_pINew;
}