Component Object Model and MAPI
This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
The Windows SDK documentation includes a comprehensive discussion of the rules for implementing objects that conform to the Component Object Model (COM). These rules address how to do the following:
Design interfaces and objects.
Implement the IUnknown interface.
Handle reference counting.
Implement apartment-threaded objects.
Although all MAPI objects are considered COM-based because they implement interfaces that inherit from IUnknown, MAPI deviates in some situations from the standard COM rules. This deviation allows developers more flexibility in their implementations. For example, a MAPI interface, like any COM interface, describes a contract between implementer and caller. Once the interface is created and published, its definition cannot and does not change. MAPI does not deviate from this description, but it relaxes the description somewhat. Implementers can choose to not implement particular methods, returning one of the following error values to the caller:
The other deviations from the standard COM rules are described in the following table.
COM programming rule
All string parameters in interface methods should be Unicode.
MAPI interfaces are defined to permit either Unicode or ANSI string parameters. Many methods that have a string parameter also have a ulFlags parameter; the width of a string parameter is indicated by the value of the MAPI_UNICODE flag in ulFlags. Some MAPI interfaces do not support Unicode and return MAPI_E_BAD_CHARWIDTH when the MAPI_UNICODE flag is set.
All interface methods should have a return type of HRESULT.
MAPI has at least one method that returns a non-HRESULT value: IMAPIAdviseSink::OnNotify.
Callers and implementers should allocate and free memory for interface parameters by using the standard COM task allocators.
All MAPI methods use the linked allocators MAPIAllocateBuffer, MAPIAllocateMore, and MAPIFreeBuffer to manage memory for interface parameters. All MAPI implementations of interfaces defined by OLE, such as IStream, use the standard COM task allocators.
All out pointer parameters must explicitly be set to NULL when a method fails.
MAPI interfaces require that out pointer parameters either be set to NULL or remain unchanged when a method fails. All MAPI implementations of interfaces defined by OLE explicitly set out parameters to NULL on failure.
Implement aggregatable objects whenever possible.
MAPI interfaces are not aggregatable.