Thread overview
CoInitializer
Feb 26, 2004
JAVIER ESTRADA
Feb 26, 2004
Matthew
Feb 26, 2004
Matthew
February 26, 2004
Matthew,

I missed a RAII that wraps the calls to CoInitialize(Ex) and CoUninitialize. I make heavy use of such a simple wrapper, and it can serve as a base class for "active" classes--those that create their own thread and enter a COM apartment, or as an automatic variable when entering COM is necessary for the length of a function call:

#ifndef _WIN32_DCOM
#define _WIN32_DCOM
#endif

#include <windef.h>   // DWORD
#include <winerror.h> // FAILED, SUCCEEDED macros
#include <objbase.h>  // CoInitializeEx, CoUninitialize

class CoInitializer
{
  CoInitializer(CoInitializer const&);
  CoInitializer& operator=(CoInitializer const&);

public:

  explicit CoInitializer(DWORD dwCoInit = COINIT_APARTMENTTHREADED)
  {
    if (FAILED(::CoInitializeEx(0, dwCoInit)))
      /*a throw clause here if desired*/;
  }

  ~CoInitializer() { ::CoUninitialize(); }
};


February 26, 2004
"JAVIER ESTRADA" <ljestrada@verizon.net> wrote in message news:c1judk$1knu$1@digitaldaemon.com...
> Matthew,
>
> I missed a RAII that wraps the calls to CoInitialize(Ex) and
CoUninitialize.
> I make heavy use of such a simple wrapper, and it can serve as a base
class
> for "active" classes--those that create their own thread and enter a COM apartment, or as an automatic variable when entering COM is necessary for the length of a function call:

Check out comstl_initialisers.h, which contains the com_initialiser and ole_initialiser classes. There's a test program in the test\comstl\initialisers_test subdirectory.

They currently use a half-hearted mechanism to attempt to prevent inheritance, so may not serve your needs in their current form.

There's also a problem with them is that they're not spelled correctly for US-English speakers, so I'm adding the appropriate typedefs in the next version. This may be how you missed them (although I would have assumed that you'd grep for CoInitialize.)

However, I'm including the latest version, which have these issues addressed now.

> #ifndef _WIN32_DCOM
> #define _WIN32_DCOM
> #endif
>
> #include <windef.h>   // DWORD
> #include <winerror.h> // FAILED, SUCCEEDED macros
> #include <objbase.h>  // CoInitializeEx, CoUninitialize
>
> class CoInitializer
> {
>   CoInitializer(CoInitializer const&);
>   CoInitializer& operator=(CoInitializer const&);
>
> public:
>
>   explicit CoInitializer(DWORD dwCoInit = COINIT_APARTMENTTHREADED)
>   {
>     if (FAILED(::CoInitializeEx(0, dwCoInit)))
>       /*a throw clause here if desired*/;
>   }
>
>   ~CoInitializer() { ::CoUninitialize(); }
> };

This is wrong! You need to match a call to CoUninitialize() *only* with a
successful call to CoInitialize(), CoInitializeEx(), and the same follows
for OleInitialize() and OleUninitialize(). MSDN says:

"A thread must call CoUninitialize once for each successful call it has made to CoInitialize or CoInitializeEx. Only the CoUninitialize call corresponding to the CoInitialize or CoInitializeEx call that initialized the library can close it."


I'm including the latest version here. This will get into 1.7.1, so you are pretty safe using it as is.

btw, I'm thinking of changing them to allow for parameterisation by an error-handling policy, so as to throw exceptions if it fails. But don't worry, as I'll make sure that all current typenames will be valid instantiations of the templates with the same semantics as they now have. :)

Cheers

Matthew



February 26, 2004
No time like the present. Here's the policy-based version.

Thanks for providing the impetus. :)

Matthew


"Matthew" <matthew.hat@stlsoft.dot.org> wrote in message news:c1k3b1$1tg4$1@digitaldaemon.com...
> "JAVIER ESTRADA" <ljestrada@verizon.net> wrote in message news:c1judk$1knu$1@digitaldaemon.com...
> > Matthew,
> >
> > I missed a RAII that wraps the calls to CoInitialize(Ex) and
> CoUninitialize.
> > I make heavy use of such a simple wrapper, and it can serve as a base
> class
> > for "active" classes--those that create their own thread and enter a COM apartment, or as an automatic variable when entering COM is necessary
for
> > the length of a function call:
>
> Check out comstl_initialisers.h, which contains the com_initialiser and ole_initialiser classes. There's a test program in the test\comstl\initialisers_test subdirectory.
>
> They currently use a half-hearted mechanism to attempt to prevent inheritance, so may not serve your needs in their current form.
>
> There's also a problem with them is that they're not spelled correctly for US-English speakers, so I'm adding the appropriate typedefs in the next version. This may be how you missed them (although I would have assumed
that
> you'd grep for CoInitialize.)
>
> However, I'm including the latest version, which have these issues
addressed
> now.
>
> > #ifndef _WIN32_DCOM
> > #define _WIN32_DCOM
> > #endif
> >
> > #include <windef.h>   // DWORD
> > #include <winerror.h> // FAILED, SUCCEEDED macros
> > #include <objbase.h>  // CoInitializeEx, CoUninitialize
> >
> > class CoInitializer
> > {
> >   CoInitializer(CoInitializer const&);
> >   CoInitializer& operator=(CoInitializer const&);
> >
> > public:
> >
> >   explicit CoInitializer(DWORD dwCoInit = COINIT_APARTMENTTHREADED)
> >   {
> >     if (FAILED(::CoInitializeEx(0, dwCoInit)))
> >       /*a throw clause here if desired*/;
> >   }
> >
> >   ~CoInitializer() { ::CoUninitialize(); }
> > };
>
> This is wrong! You need to match a call to CoUninitialize() *only* with a
> successful call to CoInitialize(), CoInitializeEx(), and the same follows
> for OleInitialize() and OleUninitialize(). MSDN says:
>
> "A thread must call CoUninitialize once for each successful call it has
made
> to CoInitialize or CoInitializeEx. Only the CoUninitialize call corresponding to the CoInitialize or CoInitializeEx call that initialized the library can close it."
>
>
> I'm including the latest version here. This will get into 1.7.1, so you
are
> pretty safe using it as is.
>
> btw, I'm thinking of changing them to allow for parameterisation by an error-handling policy, so as to throw exceptions if it fails. But don't worry, as I'll make sure that all current typenames will be valid instantiations of the templates with the same semantics as they now have.
:)
>
> Cheers
>
> Matthew
>
>
>