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
|
|
Comparsion flags. Can be used with cmp or the comparsion functors.
|
Function Documentation
|
|
VARIANT_BOOL to bool [in] converter. This is used by the generated wrappers. |
|
||||||||||
|
Make sure closing of an auto_handle_wrap_t detaches first.
|
|
||||||||||
|
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();
}
|
|
||||||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||||
|
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.
|
|
||||||||||||||||
|
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.
|
|
||||||||||
|
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.
}
|
|
||||||||||
|
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() );
|