Com type wrappers.


Namespaces

namespace  comet::impl
 Namespace for comet implementation details.
namespace  comet::impl
 Namespace for comet implementation details.
namespace  comet::impl
 Namespace for comet implementation details.
namespace  comet::impl
 Namespace for comet implementation details.
namespace  comet::impl
 Namespace for comet implementation details.

Classes

class  comet::bstr_t
class  comet::bool_out
class  comet::bool_inout
class  comet::variant_bool_t
class  comet::currency_t
struct  comet::dt_invalid_t
 Initialise date/time value as invalid.
struct  comet::dt_null_t
 Initialise date/time value as null.
struct  comet::dt_zero_t
 Initialise date/time value as zero.
class  comet::timeperiod_t
class  comet::datetime_t
class  comet::GIT_cookie< Itf >
 Type-safe GIT Cookie. More...
class  comet::GIT
 Global Interface Table wrapper. More...
class  comet::handle_policy_base_t< H, INVALID_HANDLE_ >
struct  comet::handle_nothrow_error_policy_t
struct  comet::handle_throw_error_policy_t
class  comet::auto_handle_wrap_t< C_, H, INVALID_HANDLE_, ERROR_POLICY >
struct  comet::auto_handle_t< ERROR_POLICY >
 Wrapper for HANDLE type. More...
struct  comet::auto_reference_t< T >
 Create a reference object to a handle that doesn't destroy it's contents. More...
class  comet::identity_ptr
 Represents the identity Unknown of an object. More...
class  comet::com_ptr< Itf >
 Interface smart pointer. More...
class  comet::safearray_t< T >
class  comet::uuid_t
 UUID wrapper. More...
class  comet::variant_t
 Wrapper for VARIANT type. More...
class  comet::bstr_t
class  comet::bool_out
class  comet::bool_inout
class  comet::variant_bool_t
class  comet::timeperiod_t
class  comet::datetime_t
struct  comet::handle_nothrow_error_policy_t
struct  comet::handle_throw_error_policy_t
class  comet::auto_handle_wrap_t< C_, H, INVALID_HANDLE_, ERROR_POLICY >

Typedefs

typedef auto_handle_t comet::auto_handle
 Auto handle - wrapper for HANLDE.
typedef auto_handle_t< handle_throw_error_policy_t > comet::auto_handle_throw
 Auto handle - throwing wrapper for HANDLE.

Enumerations

enum  comet::compare_flags_t {
  comet::cf_ignore_case = NORM_IGNORECASE, comet::cf_ingore_nonspace = NORM_IGNORENONSPACE, comet::cf_ignore_symbols = NORM_IGNORESYMBOLS, comet::cf_ignore_width = NORM_IGNOREWIDTH,
  comet::cf_ignore_kanatype = NORM_IGNOREKANATYPE, comet::cf_ignore_kashida = NORM_IGNOREKASHIDA
}
 Comparsion flags. More...

Functions

bstr_t comet::operator+ (const std::wstring &s, const bstr_t &t) throw (std::bad_alloc)
 Concat operation.
bstr_t comet::operator+ (const wchar_t *s, const bstr_t &t) throw (std::bad_alloc)
 Concat operation.
template<typename T> impl::auto_attach_t< T > comet::auto_attach (const T &t)
 Used to attach a raw parameter to a wrapper.
VARIANT_BOOL comet::bool_in (bool x)
template<typename CHAR> size_t comet::str_formattime (CHAR *strDest, size_t maxsize, const CHAR *format, const struct tm *timeptr)
 A wrapper for choosing strftime/wcsftime based on char type.
template<typename H, long INVALID_HANDLE_> impl::THIS_IS_NOT_ALLOWED comet::CloseHandle (const handle_policy_base_t< H, INVALID_HANDLE_ > &)
 Disallow closing of a const handle.
template<typename H, long INVALID_HANDLE_> bool comet::CloseHandle (handle_policy_base_t< H, INVALID_HANDLE_ > &rhs)
 Make sure closing of an auto_handle_wrap_t detaches first.
template<typename Itf> impl::com_cast_t< Itf > com_cast (Itf *t)
impl::com_cast_t< variant_t > com_cast (const variant_t &v)
template<typename Itf> impl::try_cast_t< Itf > comet::try_cast (const com_ptr< Itf > &t)
 Cast com_ptr.
template<typename Itf> impl::try_cast_t< Itf > try_cast (Itf *t)
impl::try_cast_t< variant_t > try_cast (const variant_t &v)
bool operator!= (const bstr_t &b, const variant_t &v)
bool operator== (const bstr_t &b, const variant_t &v)
bool operator< (const bstr_t &b, const variant_t &v)
bool operator> (const bstr_t &b, const variant_t &v)
bool operator<= (const bstr_t &b, const variant_t &v)
bool operator>= (const bstr_t &b, const variant_t &v)
impl::com_cast_t< Itf > comet::com_ptr::com_cast (const com_ptr< Itf > &t)
 Cast com_ptr.
bool comet::com_ptr::operator== (int null, const com_ptr< Itf2 > &x) throw(com_error)
 Comparison with null.
bool comet::identity_ptr::operator== (int null, const identity_ptr &x) throw(com_error)
 Comparison with null.
bool comet::com_ptr::operator!= (int null, const com_ptr< Itf > &x) throw(com_error)
 Comparison with null.
bool comet::com_ptr::operator!= (int null, const identity_ptr &x) throw(com_error)
 Comparison with null.
com_ptr< Itf > comet::com_ptr::try_cast_ptr (const impl::try_caster_t< Itf > &caster)

Variables

const double half_millisecond = 1.0/172800000.0

Comet com_ptr

Overview

The com_ptr type is essentially a reference counting wrapper for objects that support AddRef / Release in a way that is STL container compatible.

It also provides a mechanism for doing casting (QueryInterface) assignments as well as for doing assignment-compatible assignments and for providing smart wrappers for the interfaces.

What Can Be Wrapped?

The com_ptr has been designed to allow most classes to be wrapped, specifically it allows for wrapping ::IUnknown based interfaces, and also coclass implementations.

It should be noted that some coclasses can have two implementations of ::IUnknown (aggregateable coclasses being a prime example). These classes support get_unknown() which allows the com_ptr to get a the unknown responsible for the lifetime management of the object.

Assigning Pointers

There are three ways of assigning and constructing com_ptr objects, depending on your objective; direct assignment and the two cast operators com_cast and try_cast.

Direct Assignment

The first way is trivial, but quite important and is the simple assignment of one com_ptr to another. This is done in such a way as to make it possible to assign assignment compatible interfaces (eg an ::IUnknown pointer can be assigned from an ::IDispatch pointer). A compile-time error will occur if the pointers are not compatible.

Unfortunately there are certain circumstances that MSVC6 compiler does not provide a complete enough template instantiation backtrace in order to be able to directly work out an offending assignment. Our appologies, but a decent compiler would be more accomodating!

Casting Assignment

To cause a COM cast or ::QueryInterface to happen, you need to use the wrapper functions com_cast and try_cast. The cause a QueryInterface on both assignment and construction, allowing you the choice between having an exception thrown on failure (try_cast) or to silently fail leaving the object NULL (com_cast).

                        com_ptr<IViewObject> viewobj = com_cast( obj ); // <-- non-throwing query-interface
                        if (viewobj.is_null())
                        {
                                com_ptr<IViewObject2> viewobj2 = try_cast( obj ); // <-- throwing query-interface
                                viewobj = viewobj2;     // <-- Assignment between assignment compatible types.
                        }

This shows the three different ways of assigning. The first uses com_cast that causes the assignment to do a QueryInterface, but does not throw an error. The second uses try_cast that again causes the assignment to do a QueryInterface, but causes errors to be thrown. The third assignment is for assignment compatible objects only, and will cause a compiler-error unless (in this case) IViewObject2 inherits off IViewObject (which it does).

Assignment From a variant_t

Assignment to a com_ptr from a variant_t must be done by either com_cast or try_cast, as any assignment from a variant is effectively a cast.

Smart Wrappers

The com_ptr operator-> provides wrapped access to the methods on the interface. For interfaces that have been generated by tlb2h, the interface returned is a wrapper that allows access only to the wrapped methods, otherwise, access to the raw interface is default.

The design of the wrappers allows for system interfaces to be wrapped as well. There is an <::IDispatch> IDispatch wrapper defined in comet/dispatch.h that provides methods to call functions and property accessors by name or by dispatch id.

There is also a wrapper for the API TypeLibrary information interfaces defined in comet/tlbinfo.h. In addition to providing some simple wrappers to hide the raw COM types, it also provides accessor wrappers to the structs that are allocated/deallocated by the interfaces.

Implementation

It is not necessary to know how the wrappers are implemented in order to use them, however the technique is quite interesting.

They key to the wrappers is template specialisation. The operator-> returns the 'this' pointer with a reinterpret_cast to a wrap_t struct instantiated to the interface contained by the com_ptr. The default wrap_t template definition is to inherit from the interface, thus giving direct access to methods.

The tlb2h generated headers (as well as comet/tlbinfo.h and a0omet/dispatch.h) provide alternate specialisations for wrap_t that wrap the arguments and call the real methods (which would be Invoke if it is an dispinterface) by using reinterpret_cast to cast back to the original interface.

Raw COM Access

Whether calling raw COM interfaces, or trying to understand how the wrappers work, you will come across the Raw COM Acces methods. These are standard across the types (see Raw COM Acces), however com_ptr classes also have a raw() method that is equivalent to get() and proivdes access to the raw COM methods.

Enumeration Type Documentation

enum compare_flags_t
 

Comparsion flags.

Can be used with cmp or the comparsion functors.

See also:
cmp less less_equal greater greater_equal equal_to not_equal_to
Enumeration values:
cf_ignore_case  Ignore case.
cf_ingore_nonspace  Ignore nonspacing chars.
cf_ignore_symbols  Ignore symbols.
cf_ignore_width  Ignore string width.
cf_ignore_kanatype  Ignore Kana type.
cf_ignore_kashida  Ignore Arabic kashida characters.


Function Documentation

VARIANT_BOOL bool_in bool  x  )  [inline]
 

VARIANT_BOOL to bool [in] converter. This is used by the generated wrappers.

template<typename H, long INVALID_HANDLE_>
bool CloseHandle handle_policy_base_t< H, INVALID_HANDLE_ > &  rhs  ) 
 

Make sure closing of an auto_handle_wrap_t detaches first.

Returns:
true if CloseHandle was successful.

template<typename Itf>
impl::com_cast_t< Itf > com_cast const com_ptr< Itf > &  t  )  [related, inherited]
 

Cast com_ptr.

Allows QueryInterface when casting to different com_ptr type.

                        com_ptr<IFoo> foo;
                        com_ptr<IBar> bar;
                        bar = com_cast(foo);
                        if (!bar.is_null()) {
                                // Cast is ok.
                                bar->DoTheThing();
                        }
Parameters:
t com_ptr to cast

template<typename Itf>
bool operator!= int  null,
const identity_ptr x
throw(com_error) [related, inherited]
 

Comparison with null.

Only comparison with a value of zero is allowed. Non-zero values will result in E_POINTER (wrapped in com_error) being thrown.

Exceptions:
com_error Throws E_POINTER if a non-zero value is specified.

template<typename Itf>
bool operator!= int  null,
const com_ptr< Itf > &  x
throw(com_error) [related, inherited]
 

Comparison with null.

Only comparison with a value of zero is allowed. Non-zero values will result in E_POINTER (wrapped in com_error) being thrown.

Exceptions:
com_error Throws E_POINTER if a non-zero value is specified.

bool operator== int  null,
const identity_ptr x
throw(com_error) [related, inherited]
 

Comparison with null.

Only comparison with a value of zero is allowed. Non-zero values will result in E_POINTER (wrapped in com_error) being thrown.

Exceptions:
com_error Throws E_POINTER if a non-zero value is specified.

template<typename Itf>
bool operator== int  null,
const com_ptr< Itf2 > &  x
throw(com_error) [related, inherited]
 

Comparison with null.

Only comparison with a value of zero is allowed. Non-zero values will result in E_POINTER (wrapped in com_error) being thrown.

Exceptions:
com_error Throws E_POINTER if a non-zero value is specified.

template<typename Itf>
impl::try_cast_t<Itf> try_cast const com_ptr< Itf > &  t  )  [inline]
 

Cast com_ptr.

Allows QueryInterface when casting to different com_ptr type.

                        com_ptr<IFoo> foo;
                        com_ptr<IBar> bar;
                        try {
                                bar = try_cast(foo);
                                bar->DoTheThing();
                        } catch (com_error&) {
                                // Cast didn't work.
                        }

template<typename Itf>
com_ptr< Itf > try_cast_ptr const impl::try_caster_t< Itf > &  caster  )  [related, inherited]
 

Version of try_cast more to the style of dynamic_cast. This is aimed at being used for casts that get used once in an environment with many interfaces.

                com_ptr<IDomSession> session;
                com_ptr<IDomUser>   = try_cast( try_cast_ptr<ISession>(session)->User() );
The impl::try_caster_t is implementation only - let the compiler do the cast from com_ptr to impl::try_caster_t. Note that try_cast would still be the preferred method for most casts.
See also:
try_cast