5    The COM Library

5.1    COM Application Responsibilities

All applications, that is, running programs that define a task or a process be they client or servers, have specific responsibilities. This chapter examines the roles and responsibilities of all COM applications and the necessary COM library support functions for those responsibilities.

In short, any application that makes use of COM, client or server, has three specific responsibilities to insure proper operation with other components:

  1. On application startup, initialize the COM Library.

  2. On application shutdown, uninitialize the COM Library to allow it to free resources and perform any cleanup operations as necessary.

Each of these responsibilities requires support from the COM Library itself as detailed in the following sections. For convenience, initialization and uninitialization are described together. Additional COM Library functions related to initialization and memory management are also given in this chapter.

5.2    Library Initialization / Uninitialization

To use basic COM services, all COM threads of execution in clients and out-of-process servers must call either the CoInitialize() or the CoInitializeEx() function before calling any other COM function except memory allocation calls. CoInitializeEx() replaces the other function, adding a parameter that allows you to specify the threading model of the thread--either apartment-threaded or free-threaded. A call to CoInitialize() simply sets the threading model to apartment-threaded. For information on threading in clients and servers, refer to Chapter 6.

In-process servers do not call the initialization functions, because they are being loaded into a process that has already done so. As a result, in-process servers must set their threading model in the registry under the InprocServer32 key. For detailed information on threading issues in in-process servers, refer to Section Section 6.5.

It is also important to uninitialize the library. For each call to CoInitialize() or CoInitializeEx(), there must be a corresponding call to CoUninitialize().

5.3    Memory Management

[Footnote 39] As was articulated earlier in this specification, when ownership of allocated memory is passed through an interface, COM requires [Footnote 39] that the memory be allocated with a specific ``task allocator.'' Most general purpose access to the task allocator is provided through the IMalloc() interface instance returned from CoGetMalloc(). Simple shortcut allocation and freeing APIs are also provided in the form of CoTaskMemAlloc() and CoTaskMemFree().

5.3.1    Memory Allocation Example

An object may need to pass memory between it and the client at some point in the object's lifetime--this applies to in-process as well as out-of-process servers. When such a situation arises the object must use the task allocator as described in Chapter 2. That is, the object must allocate memory whose ownership is transferred from one party to another through an interface function by using the local task allocator.

CoGetMalloc() provides a convenient way for objects to allocate working memory as well. For example, when the TextRender object (see Section Section 4.6) under consideration in this document loads text from a file in the function IPersistFile::Load() (that is, CTextRender::Load()) it will want to make a memory copy of that text. It would use the task allocator for this purpose as illustrated in the following code (unnecessary details of opening files and reading data are omitted for simplicity):

//Implementation of IPersistFile::Load()
HRESULT CTextRender::Load(char *pszFile, DWORD grfMode) {
 int       hFile;
 DWORD     cch;
 IMalloc() * pIMalloc;
 HRESULT   hr;
 /*
  * Open the file and seek to the end to set the
  * cch variable to the length of the file.
  */
 hr=CoGetMalloc(MEMCTX_TASK, &pIMalloc);
 if (FAILED(hr))
  //Close file and return failure
 psz=pIMalloc->Alloc(cch);
 pIMalloc->Release();
 if (NULL==psz)
  //Close file and return failure
 //Read text into psz buffer and close file
 //Save memory pointer and return success
 m_pszText=psz;
 return NOERROR;
 }

If an object will make many allocations throughout its lifetime, it makes sense to call CoGetMalloc() once when the object is created, store the IMalloc() pointer in the object (m_pIMalloc or such), and call IMalloc::Release() when the object is destroyed. Alternatively, the APIs CoTaskMemAlloc() and its friends may be used.

5.4    COM Library Interface Descriptions

5.4.1    IMalloc

IMalloc() allocates, frees, and manages memory.

When to Implement

In general, you should not implement IMalloc(), instead using the COMOLE implementation, which is guaranteed to be thread-safe in managing task memory. You get a pointer to the COMOLE task allocator object's IMalloc() through a call to the CoGetMalloc() function.

When to Use

Call the methods of IMalloc() to allocate and manage memory. The COMOLE libraries and object handlers also call the IMalloc() methods to manage memory. Object handlers should call CoGetMalloc() to get a pointer to the IMalloc() implementation on the task allocator object, and use the implementation of those methods to manage task memory.

The IMalloc() methods Alloc, Free, and Realloc are similar to the C library functions malloc, free, and realloc. For debugging, refer to the functions CoRegisterMallocSpy() and CoRevokeMallocSpy().

Table 5-1:  IMalloc Methods in VTable Order

IUnknown Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 5-2:  IMalloc Methods

IMalloc() Methods Description
Alloc Allocates a block of memory.
Realloc Changes the size of a previously allocated block of memory.
Free Frees a previously allocated block of memory.
GetSize Returns the size in bytes of a previously allocated block of memory.
DidAlloc Determines if this instance of IMalloc() was used to allocate the specified block of memory.
HeapMinimize Minimizes the heap by releasing unused memory to the operating system.

See Also

CoGetMalloc(), IMallocSpy(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMalloc::Alloc()

NAME

IMalloc::Alloc() - Allocates a block of memory.

Synopsis

#include <objidl.h>

void * Alloc(
        ULONG cb );

Description

The IMalloc::Alloc() method allocates a memory block in essentially the same way that the C Library malloc function does.

The initial contents of the returned memory block are undefined - there is no guarantee that the block has been initialized, so you should initialize it in your code. The allocated block may be larger than cb bytes because of the space required for alignment and for maintenance information.

If cb is zero, IMalloc::Alloc() allocates a zero-length item and returns a valid pointer to that item. If there is insufficient memory available, IMalloc::Alloc() returns NULL.

Applications should always check the return value from this method, even when requesting small amounts of memory, because there is no guarantee the memory will be allocated.

Parameters

cb

[in] Size , in bytes, of the memory block to be allocated.

Return Values

If successful, Alloc returns a pointer to the allocated memory block.

NULL

If insufficient memory is available, Alloc returns NULL.

See Also

IMalloc::Free(), IMalloc::Realloc(), CoTaskMemAlloc()  

IMalloc::DidAlloc()

NAME

IMalloc::DidAlloc() - Determines if this allocator was used to allocate the specified block of memory.

Synopsis

#include <objidl.h>

int DidAlloc(
        void * pv );

Description

Calling IMalloc::DidAlloc() is useful if a application is using multiple allocations, and needs to know whether a previously allocated block of memory was allocated by a particular allocation.

Parameters

pv

[in] Pointer to the memory block; can be a NULL pointer, in which case, -1 is returned.

Return Values

1

The memory block was allocated by this IMalloc() instance.

0

The memory block was not allocated by this IMalloc() instance.

-1

DidAlloc is unable to determine whether or not it allocated the memory block.

See Also

IMalloc::Alloc(), IMalloc::HeapMinimize(), IMalloc::Realloc()  

IMalloc::Free()

NAME

IMalloc::Free() - Frees a previously allocated block of memory.

Synopsis

#include <objidl.h>

void Free(
        void * pv );

Description

IMalloc:Free frees a block of memory previously allocated through a call to IMalloc::Alloc() or IMalloc::Realloc(). The number of bytes freed equals the number of bytes that were allocated. After the call, the memory block pointed to by pv is invalid and can no longer be used.

The pv parameter can be NULL. If so, this method has no effect.

Parameters

pv

[in] Pointer to the memory block to be freed.

See Also

IMalloc::Alloc(), IMalloc::Realloc(), CoTaskMemFree()  

IMalloc::GetSize()

NAME

IMalloc::GetSize() - Returns the size (in bytes) of a memory block previously allocated with IMalloc::Alloc() or IMalloc::Realloc().

Synopsis

#include <objidl.h>

ULONG GetSize(
        void * pv );

Description

To get the size in bytes of a memory block, the block must have been previously allocated with IMalloc::Alloc() or IMalloc::Realloc(). The size returned is the actual size of the allocation, which may be greater than the size requested when the allocation was made.

Parameters

pv

[in] Pointer to the memory block for which the size is requested.

Return Values

The size of the allocated memory block in bytes or, if pv is a NULL pointer, -1.

See Also

IMalloc::Alloc(), IMalloc::Realloc()  

IMalloc::HeapMinimize()

NAME

IMalloc::HeapMinimize() - Minimizes the heap as much as possible by releasing unused memory to the operating system, coalescing adjacent free blocks and committing free pages.

Synopsis

#include <objidl.h>

void HeapMinimize(
         );

Description

Calling IMalloc::HeapMinimize() is useful when an application has been running for some time and the heap may be fragmented.

See Also

IMalloc::Alloc(), IMalloc::Free(), IMalloc::Realloc()  

IMalloc::Realloc()

NAME

IMalloc::Realloc() - Changes the size of a previously allocated memory block.

Synopsis

#include <objidl.h>

void *Realloc(
        void * pv,
        ULONG cb );

Description

IMalloc::Realloc() reallocates a block of memory, but does not guarantee that the contents of the returned memory block are initialized. Therefore, the caller is responsible for intializing it in code, subsequent to the reallocation. The allocated block may be larger than cb bytes because of the space required for alignment and for maintenance information.

The pv argument points to the beginning of the memory block. If pv is NULL, IMalloc::Realloc() allocates a new memory block in the same way that IMalloc::Alloc() does. If pv is not NULL, it should be a pointer returned by a prior call to IMalloc::Alloc().

The cb argument specifies the size (in bytes) of the new block. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a different memory location, the pointer returned by IMalloc::Realloc() is not guaranteed to be the pointer passed through the pv argument. If pv is not NULL and cb is zero, then the memory pointed to by pv is freed.

IMalloc::Realloc() returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough memory available to expand the block to the given size. In the first case, the original block is freed; in the second, the original block is unchanged.

The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.

Parameters

pv

[in] Pointer to the memory block to be reallocated. The pointer can have a NULL value, as discussed in the following Remarks section.

cb

[in] Size of the memory block (in bytes) to be reallocated. It can be zero, as discussed in the following remarks.

Return Values

Reallocated memory block

Memory block successfully reallocated.

NULL

Insufficient memory or cb is zero and pv is not NULL.

See Also

IMalloc::Alloc(), IMalloc::Free()

5.4.2    IMallocSpy

The IMallocSpy() interface is a debugging interface that allows application developers to monitor (spy on) memory allocation, detect memory leaks and simulate memory failure in calls to IMalloc() methods.

Caution: The IMallocSpy() interface is intended to be used only to debug application code under development. Do not ship this interface to retail customers of your application, because it causes severe performance degradation and could conflict with user-installed software to produce unpredictable results.

When to Implement

Implement this interface to debug memory allocation during application development.

When to Use

When an implementation of IMallocSpy() is registered with CoRegisterMallocSpy(), COM calls the pair of IMallocSpy() methods around the corresponding IMalloc() method. You would not make direct calls to IMallocSpy() methods. The COM SDK contains a sample implementation of IMallocSpy(). The call to the pre-method through the return from the corresponding post-method is guaranteed to be thread-safe in multi-threaded operations.

Table 5-3:  IMallocSpy Methods in Vtable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 5-4:  IMallocSpy Methods

IMallocSpy() Methods Description
PreAlloc() Called before invoking IMalloc::Alloc() , and may extend or modify the allocation to store debug information.
PostAlloc() Called after invoking IMalloc::Alloc().
PreFree() Called before invoking IMalloc::Free() .
PostFree() Called after invoking IMalloc::Free().
PreRealloc() Called before invoking IMalloc::Realloc() .
PostRealloc() Called after invoking IMalloc::Realloc().
PreGetSize() Called before invoking IMalloc::GetSize() .
PostGetSize() Called after invoking IMalloc::GetSize().
PreDidAlloc() Called before invoking IMalloc::DidAlloc() .
PostDidAlloc() Called after invoking IMalloc::DidAlloc().
PreHeapMinimize() Called before invoking IMalloc::DidAlloc() .
PostHeapMinimize() Called after invoking IMalloc::HeapMinimize() .

See Also

IMalloc(), CoGetMalloc(), CoRegisterMallocSpy()  

IMallocSpy::PreAlloc()

NAME

IMallocSpy::PreAlloc() - Called just prior to invoking IMalloc::Alloc().

Synopsis

#include <objidl.h>

ULONG PreAlloc(
        ULONG cbRequest );

Description

The IMallocSpy::PreAlloc() implementation may extend and/or modify the allocation to store debug-specific information with the allocation.

PreAlloc can force memory allocation failure by returning 0, allowing testing to ensure that the application handles allocation failure gracefully in all cases. In this case, PostAlloc is not called and Alloc returns NULL. Forcing allocation failure is effective only if cbRequest is not equal to 0. If PreAlloc is forcing failure by returning NULL, PostAlloc is not called. However, if IMalloc::Alloc() encounters a real memory failure and returns NULL, PostAlloc is called.

The call to PreAlloc through the return from PostAlloc is guaranteed to be thread safe.

Parameters

cbRequest

[in] Number of bytes specified in the allocation request the caller is passing to IMalloc::Alloc() .

Return Values

The byte count actually passed to IMalloc::Alloc(), which should be greater than or equal to the value of cbRequest.

See Also

IMalloc::Alloc(), IMallocSpy::PostAlloc(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PostAlloc()

NAME

IMallocSpy::PostAlloc() - Called just after invoking IMalloc::Alloc(), taking as input a pointer to the IMalloc::Alloc() caller's allocation, and returning a pointer to the actual allocation.

Synopsis

#include <objidl.h>

void * PostAlloc(
        void * pActual );

Description

When a spy object implementing IMallocSpy() is registered with CoRegisterMallocSpy(), COM calls IMallocSpy::PostAlloc() after any call to IMalloc::Alloc(). It takes as input a pointer to the allocation done by the call to IMalloc::Alloc(), and returns a pointer to the beginning of the total allocation, which could include a forward offset from the other value if IMallocSpy::Prealloc() was implemented to attach debug information to the allocation in this way. If not, the same pointer is returned, and also becomes the return value to the caller of IMalloc::Alloc().

Parameters

pActual

[in] Pointer to the allocation done by IMalloc::Alloc() .

Return Values

A pointer to the beginning of the memory block actually allocated. This pointer is also returned to the caller of IMalloc::Alloc(). If debug information is written at the front of the caller's allocation, this should be a forward offset from pActual. The value is the same as pActual if debug information is appended or if no debug information is attached.

See Also

IMalloc::Alloc(), IMallocSpy::PreAlloc(), CoRegisterMallocSpy(),  

IMallocSpy::PreDidAlloc()

NAME

IMallocSpy::PreDidAlloc() - Called by COM just prior to invoking IMalloc::DidAlloc().

Synopsis

#include <objidl.h>

void * PreDidAlloc(
        void * pRequest,
        BOOL fSpyed );

Description

When a spy object implementing IMallocSpy() is registered with CoRegisterMallocSpy(), COM calls this method immediately before any call to IMalloc::DidAlloc(). This method is included for completeness and consistency--it is not anticipated that developers will implement significant functionality in this method.

Parameters

pRequest

[in] Pointer the caller is passing to IMalloc::DidAlloc().

fSpyed

[in] TRUE if the allocation was done while this spy was active.

Return Values

The pointer for which allocation status is determined. This pointer is passed to PostDidAlloc as the fActual parameter.

See Also

IMalloc::DidAlloc(), IMallocSpy::PostDidAlloc(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PostDidAlloc()

NAME

IMallocSpy::PostDidAlloc() - Called just after invoking IMalloc::DidAlloc().

Synopsis

#include <objidl.h>

int PostDidAlloc(
        void * pRequest,
        BOOL fSpyed,
        int fActual );

Description

When a spy object implementing IMallocSpy() is registered with CoRegisterMallocSpy(), COM calls this method immediately after any call to IMalloc::DidAlloc(). This method is included for completeness and consistency--it is not anticipated that developers will implement significant functionality in this method. For convenience, pRequest, the original pointer passed in the call to IMalloc::DidAlloc(), is passed to PostDidAlloc. In addition, the parameter fActual is a boolean that indicates whether this value was actually passed to IMalloc::DidAlloc(). If not, it would indicate that IMallocSpy::PreDidAlloc() was implemented to alter this pointer for some debugging purpose.

The fSpyed parameter is a boolean that indicates whether the allocation was done while the current spy object was active.

Parameters

pRequest

[in] Pointer specified in the original call to IMalloc::DidAlloc() .

fSpyed

[in] TRUE if the allocation was done while this spy was active.

fActual

[in] Actual value returned by IMalloc::DidAlloc().

Return Values

The value returned to the caller of IMalloc::DidAlloc().

See Also

IMalloc::DidAlloc(), IMallocSpy::PreDidAlloc(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PreFree()

NAME

IMallocSpy::PreFree() - Called just before invoking IMalloc::Free() to ensure that the pointer passed to IMalloc::Free() points to the beginning of the actual allocation.

Synopsis

#include <objidl.h>

void * PreFree(
        void * pRequest,
        BOOL fSpyed );

Description

If IMallocSpy::PreAlloc() modified the original allocation request passed to IMalloc::Alloc() (or IMalloc::Realloc()), IMallocSpy::PreFree() must supply a pointer to the actual allocation, which COM will pass to IMalloc::Free(). For example, if the PreAlloc/PostAlloc pair attached a header used to store debug information to the beginning of the caller's allocation, PreFree must return a pointer to the beginning of this header, so all of the block that was allocated can be freed.

Parameters

pRequest

[in] Pointer to the block of memory that the caller is passing to IMalloc::Free().

fSpyed

[in] TRUE if the pRequest parameter of IMallocSpy::PreFree() was allocated while the spy was installed. This value is also passed to IMallocSpy::PostFree().

Return Values

The actual pointer to pass to IMalloc::Free().

See Also

IMalloc::Free(), IMallocSpy::PostFree(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PostFree()

NAME

IMallocSpy::PostFree() - Called just after invoking IMalloc::Free().

Synopsis

#include <objidl.h>

void PostFree(
        BOOL fSpyed );

Description

When a spy object implementing IMallocSpy() is registered with CoRegisterMallocSpy(), COM calls this method immediately after any call to IMalloc::Free(). This method is included for completeness and consistency--it is not anticipated that developers will implement significant functionality in this method. On return, the fSpyed parameter simply indicates whether the memory was freed while the current spy was active.

Parameters

fSpyed

[in] TRUE if the memory block to be freed was allocated while the current spy was active, otherwise FALSE.

See Also

IMalloc::Free(), IMallocSpy::PreFree(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PreGetSize()

NAME

IMallocSpy::PreGetSize() - Called by COM just prior to any call to IMalloc::GetSize().

Synopsis

#include <objidl.h>

void * PreGetSize(
        void * pRequest,
        BOOL fSpyed );

Description

The PreGetSize method receives as its pRequest parameter the pointer the caller is passing to IMalloc::GetSize(). It must then return a pointer to the actual allocation, which may have altered pRequest in the implementation of either the PreAlloc or PreRealloc methods of IMallocSpy(). The pointer to the true allocation is then passed to IMalloc::GetSize() as its pv parameter. IMalloc::GetSize() then returns the size determined, and COM passes this value to IMallocSpy::PostGetSize() in cbActual.

The size determined by IMalloc::GetSize() is the value returned by the Win32 function HeapSize. On Windows NT, this is the size originally requested. On Windows 95, memory allocations are done on eight-byte boundaries. For example, a memory allocation request of 27 bytes on Windows NT would return an allocation of 32 bytes and GetSize would return 27. On Windows 95, the same request would return an allocation of 28 bytes and GetSize would return 28. Implementers of IMallocSpy::PostGetSize() cannot assume, for example, that if cbActual is sizeof(debug_header), that the value is the actual size of the user's allocation.

Parameters

pRequest

[in] Pointer the caller is passing to IMalloc::GetSize().

fSpyed

[in] TRUE if the allocation was done while the spy was active.

Return Values

Pointer to the actual allocation for which the size is to be determined.

See Also

IMalloc::GetSize(), IMallocSpy::PostGetSize(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PostGetSize()

NAME

IMallocSpy::PostGetSize() - Called just after invoking IMalloc::GetSize().

Synopsis

#include <objidl.h>

ULONG PostGetSize(
        ULONG cbActual,
        BOOL fSpyed );

Description

The size determined by IMalloc::GetSize() is the value returned by the Win32 function HeapSize. On Windows NT, this is the size originally requested. On Windows 95, memory allocations are done on eight-byte boundaries. For example, a memory allocation request of 27 bytes on Windows NT would return an allocation of 32 bytes and GetSize would return 27. On Windows 95, the same request would return an allocation of 28 bytes and GetSize would return 28. Implementers of IMallocSpy::PostGetSize() cannot assume, for example, that if cbActual is sizeof(debug_header), that the value is the actual size of the user's allocation.

Parameters

cbActual

[in] Actual number of bytes in the allocation, as returned by IMalloc::GetSize() .

fSpyed

[in] TRUE if the allocation was done while a spy was active.

Return Values

The same value returned by IMalloc::GetSize(), which is the size of the allocated memory block in bytes.

See Also

IMalloc::GetSize(), IMallocSpy::PreGetSize(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PreHeapMinimize()

NAME

IMallocSpy::PreHeapMinimize() - Called just prior to invoking IMalloc::HeapMinimize().

Synopsis

#include <objidl.h>

void PreHeapMinimize(
        void );

Description

This method is included for completeness; it is not anticipated that developers will implement significant functionality in this method.

See Also

IMalloc::HeapMinimize(), IMallocSpy::PostHeapMinimize(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PostHeapMinimize()

NAME

IMallocSpy::PostHeapMinimize() - Called just after invoking IMalloc::HeapMinimize().

Synopsis

#include <objidl.h>

void PostHeapMinimize(
        void );

Description

When a spy object implementing IMallocSpy() is registered with CoRegisterMallocSpy(), COM calls this method immediately after any call to IMalloc::Free(). This method is included for completeness and consistency--it is not anticipated that developers will implement significant functionality in this method.

See Also

IMalloc::HeapMinimize(), IMallocSpy::PreHeapMinimize(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PreRealloc()

NAME

IMallocSpy::PreRealloc() - Called just before invoking IMalloc::Alloc().

Synopsis

#include <objidl.h>

ULONG PreRealloc(
        void * pRequest,
        ULONG cbRequest,
        void ** ppNewRequest,
        BOOL fSpyed );

Description

The IMallocSpy::PreRealloc() implementation may extend and/or modify the allocation to store debug-specific information with the allocation. Thus, the ppNewRequest parameter may differ from pRequest, a pointer to the request specified in the original call to IMalloc::Realloc().

PreRealloc can force memory allocation failure by returning 0, allowing testing to ensure that the application handles allocation failure gracefully in all cases. In this case, PostRealloc is not called and Realloc returns NULL. However, if IMalloc::Realloc() encounters a real memory failure and returns NULL, PostRealloc is called. Forcing allocation failure is effective only if cbRequest is not equal to 0.

Parameters

pRequest

[in] Pointer specified in the original call to IMalloc::Realloc(), indicating the the memory block to be reallocated.

cbRequest

[in] Memory block's byte count as specified in the original call to IMalloc::Realloc().

ppNewRequest

[out] Address of pointer variable that receives a pointer to the actual memory block to be reallocated. This may be different from the pointer in pRequest if the implementation of IMallocSpy::PreRealloc() extends or modifies the reallocation. This is an out pointer and should always be stored by PreRealloc.

fSpyed

[in] TRUE if the original allocation was done while the spy was active.

Return Values

The actual byte count to be passed to IMalloc::Realloc().

See Also

IMalloc::Realloc(), IMallocSpy::PostRealloc(), CoRegisterMallocSpy(), CoRevokeMallocSpy()  

IMallocSpy::PostRealloc()

NAME

IMallocSpy::PostRealloc() - Called after invoking IMalloc::Realloc().

Synopsis

#include <objidl.h>

void * PostRealloc(
        void * pActual,
        BOOL fSpyed );

Parameters

pActual

[in] Pointer to the memory block reallocated by IMalloc::Realloc().

fSpyed

[in] If TRUE, the original memory allocation was done while the spy was active.

Return Values

A pointer to the beginning of the memory block actually allocated. This pointer is also returned to the caller of IMalloc::Realloc(). If debug information is written at the front of the caller's allocation, it should be a forward offset from pActual. The value should be the same as pActual if debug information is appended or if no debug information is attached.

See Also

IMalloc::Realloc(), IMallocSpy::PreRealloc(), CoRegisterMallocSpy(), CoRevokeMallocSpy()

5.4.3    IOleContainer

The IOleContainer interface is used to enumerate objects in a compound document or lock a container in the running state. Container and object applications both implement this interface.

When to Implement

Applications that support links and links to embedded objects implement this interface to provide object enumeration, name parsing, and silent updates of link sources. Simple, nonlinking containers do not need to implement IOleContainer if it is useful mainly to support links to embedded objects.

When to Use

Call IOleContainer to enumerate the objects in a compound document or to lock a container so that silent updates of link sources can be carried out safely. Many applications inherit the functions of IOleContainer by implementing IOleItemContainer(), which is used to bind item monikers.

Table 5-5:  IOleContainer Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 5-6:  IParseDisplayName Method

IParseDisplayName() Method Description
ParseDisplayName() Parses object's display name to form moniker.

Table 5-7:  IOleContainer Methods

IOleContainer Methods Description
EnumObjects() Enumerates objects in a container.
LockContainer() Keeps container running until explicitly released.

See Also

IOleItemContainer(), IParseDisplayName()  

IOleContainer::EnumObjects()

NAME

IOleContainer::EnumObjects() - Enumerates objects in the current container.

Synopsis

#include <ole2.h>

HRESULT EnumObjects(
        DWORD grfFlags,
        IEnumUnknown ** ppenum );

Description

A container should implement EnumObjects to enable programmatic clients to find out what objects it holds. This method, however, is not called in standard linking scenarios.

Parameters

grfFlags

[in] Value that specifies which objects in a container are to be enumerated, as defined in the enumeration OLECONTF.

ppenum

[out] Address of IEnumUnknown()* pointer variable that receives the interface pointer to the enumerator object. Each time a container receives a successful call to EnumObjects, it must increase the reference count on the *ppenum pointer the method returns. It is the caller's responsibility to call IUnknown::Release() when it is done with the pointer. If an error is returned, the implementation must set *ppenum to NULL.

Return Values

This method supports the standard return value E_FAIL, as well as the following:

S_OK

Enumerator successfully returned.

E_NOTIMPL

Object enumeration not supported.

See Also

IEnumUnknown(), IOleItemContainer(), OLECONTF  

IOleContainer::LockContainer()

NAME

IOleContainer::LockContainer() - Keeps an embedded object's container running.

Synopsis

#include <ole2.h>

HRESULT LockContainer(
        BOOL fLock );

Description

An embedded object calls IOleContainer::LockContainer to keep its container running when the object has link clients that require an update. If an end user selects File Close from the container's menu, however, the container ignores all outstanding LockContainer locks and closes the document anyway.

Notes to Callers

When an embedded object changes from the loaded to the running state, it should call IOleContainer::LockContainer with the fLock parameter set to TRUE. When the embedded object shuts down (transitions from running to loaded), it should call IOleContainer::LockContainer with the fLock parameter set to FALSE.

Each call to LockContainer with fLock set to TRUE must be balanced by a call to LockContainer with fLock set to FALSE. Object applications typically need not call LockContainer; the default handler makes these calls automatically for object applications implemented as .EXEs as the object makes the transition to and from the running state. Object applications not using the default handler, such as DLL object applications, must make the calls directly.

An object should have no strong locks on it when it registers in the Running Object Table, but it should be locked as soon as the first external client connects to it. Therefore, following registration of the object in the Running Object Table, object handlers and DLL object applications, as part of their implementation of IRunnableObject::Run(), should call IOleContainer::LockContainer(TRUE) to lock the object.

Notes to Implementors

The container must keep track of whether and how many calls to LockContainer(TRUE) have been made. To increment or decrement the reference count, IOleContainer::LockContainer calls CoLockObjectExternal() with a flag set to match fLock.

Parameters

fLock

[in] Value that specifies whether to lock (TRUE) or unlock (FALSE) a container.

Return Values

This method supports the standard return values E_FAIL and E_OUTOFMEMORY, as well as the following:

S_OK

Container was locked successfully.

See Also

CoLockObjectExternal(), IRunnableObject::Run()

5.4.4    IPersistMoniker

Objects, especially asynchronous-aware objects, can expose the IPersistMoniker() interface to obtain more control over the way they bind to their persistent data. Existing moniker implementations call QueryInterface() on the client object for persistence interfaces such as IPersistFile(), IPersistStream[Init](), or IPersistStorage() as part of their IMoniker::BindToObject() implementation when they are instantiating and initializing the object. The IPersistMoniker() interface allows moniker implementations and other applications that instantiate objects from persistent data to give control to the object being instantiated over binding to its persistent data. An object could, for example, implement IPersistMoniker::Load() by calling IMoniker::BindToStorage() for the interface it prefers: IStorage(), IStream(), asynchronous binding, etc. Unlike some other persistent object interfaces, IPersistMoniker() does not include an InitNew() method. This means that IPersistMoniker() cannot be used to initialize an object to a freshly initialized state. Clients of IPersistMoniker() who wish to initialize the object should QueryInterface() for a different persistence interface that contains an InitNew() method, such as IPersistStreamInit(), IPersistMemory(), or IPersistPropertyBag(). Then, the client can use the InitNew() method found in the other persistence interface to initialize the object. The client can still safely used IPersistMoniker() to save the persistent state of the object. The IPersistMoniker() contract inherits its definition from the IPersist() interface, and includes the GetClassID() method of IPersist().

When to Implement

Implement IPersistMoniker() on any object that can be saved persistently to multiple storage mediums or can take advantage of any of the asynchronous stream, storage, or IMoniker::BindToStorage() behavior described above.

When to Use

Custom moniker implementations should support IPersistMoniker() as the most flexible persistence interface in their implementation of IMoniker::BindToObject() if they are instantiating an arbitrary class and need to initialize it from persistent data. Typically, these monikers should use the published persistence interfaces in the following order: IPersistMoniker(), IPersistStream[Init], IPersistStorage(), IPersistFile(), and IPersistMemory().

Table 5-8:  IPersistMoniker Methods in Vtable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments the reference count.
Release() Decrements the reference count.

Table 5-9:  IPersist Method

IPersist() Method Description
GetClassID() Returns the class identifier (CLSID) for the object.

Table 5-10:  IPersistMoniker Methods

IPersistMoniker() Methods Description
IsDirty() Checks an object for changes since it was last saved.
Load() Loads an object using a specified moniker.
Save() Saves the object, specifying a destination moniker.
SaveCompleted() Notifies the object that the save operation is complete.
GetCurMoniker() Gets the current moniker for the object.

 

IPersistMoniker::GetCurMoniker()

NAME

IPersistMoniker::GetCurMoniker() - Retrieves the moniker that refers to the object's persistent state.

Synopsis

#include <urlmon.h>

HRESULT GetCurMoniker(
        IMoniker ** ppmkCur );

Description

Typically, this method returns the moniker last passed to the object by means of IPersistMoniker::Load(), IPersistMoniker::Save, or IPersistMoniker::SaveCompleted().

Parameters

ppmkCur

[out] Address of IMoniker()* pointer variable that receives the interface pointer to the object's current persistent state.

Return Values

See Also

IPersistMoniker::Load(), IPersistMoniker::Save(), IPersistMoniker::SaveCompleted()  

IPersistMoniker::IsDirty()

NAME

IPersistMoniker::IsDirty() - Checks an object for changes since it was last saved.

Synopsis

#include <urlmon.h>

HRESULT IsDirty(
        void );

Description

IPersistMoniker::IsDirty() checks whether an object has changed since it was last saved so you can avoid losing information in objects that have not yet been saved.

Return Values

S_OK

The object has changed since it was last saved.

S_FALSE

The object has not changed since the last save.

See Also

IPersistMoniker::Save()  

IPersistMoniker::Load()

NAME

IPersistMoniker::Load() - Loads the object from its persistent state indicated by a supplied moniker.

Synopsis

#include <urlmon.h>

HRESULT Load(
        BOOL fFullyAvailable,
        IMoniker * pmkSrc,
        IBindCtx * pbc,
        DWORD grfMode );

Description

Typically, the object will immediately bind to its persistent state through a call to the source moniker's IMoniker::BindToStorage() method, requesting either the IStream() or IStorage() interface.

Parameters

fFullyAvailable

[in] If TRUE, then the data referred to by the moniker has already been loaded once, and subsequent binding to the moniker should be synchronous. If FALSE, then an asynchronous bind operation should be launched.

pmkSrc

[in] Pointer to a moniker that references the persistent state for the object to be loaded.

pbc

[in] Pointer to the IBindCtx() interface for the bind context to be used for any moniker binding during this method.

grfMode

[in] A combination of values from the STGM enumeration which indicate the access mode to use when binding to the persistent state. The IPersistMoniker::Load() method can treat this value as a suggestion, adding more restrictive permissions if necessary. If grfMode is zero, the implementation should bind to the persistent state using default permissions.

Return Values

S_OK

The object was successfully loaded.

E_INVALIDARG

One or more parameters are invalid.

See Also

IPersistMoniker::Save(), IPersistMoniker::SaveCompleted()  

IPersistMoniker::Save()

NAME

IPersistMoniker::Save() - Requests that the object save itself to the location referred to by pmkDst.

Synopsis

#include <urlmon.h>

HRESULT Save(
        IMoniker * pmkDst,
        IBindCtx * pbc,
        BOOL fRemember );

Parameters

pmkDst

[in] Pointer to the moniker referencing the location where the object should persistently store itself. The object typically binds to the location through a call to pmkDst->BindToStorage, requesting either the IStream() or IStorage() interface. This parameter can be NULL, in which case the object should save itself to the same location referred to by the moniker passed to it in IPersistMoniker::Load(). Using the NULL value, can act as an optimization to prevent the object from binding, since it has typically already bound to the moniker when it was loaded.

pbc

[in] Pointer to IBindCtx() for the bind context to be used for any moniker binding during this method.

fRemember

[in] Indicates whether pmkDst is to be used as the reference to the current persistent state after the save. If TRUE, pmkDst becomes the reference to the current persistent state and the object should clear its dirty flag after the save. If FALSE, this save operation is a ``Save A Copy As ...'' operation. In this case, the reference to the current persistent state is unchanged, and the object should not clear its dirty flag. If pmkDst is NULL, the implementation should ignore the fRemember flag.

Return Values

S_OK

The object was successfully saved.

E_INVALIDARG

One or more parameters are invalid.

See Also

IPersistMoniker::GetCurMoniker(), IPersistMoniker::Load(), IPersistMoniker::SaveCompleted()  

IPersistMoniker::SaveCompleted()

NAME

IPersistMoniker::SaveCompleted() - Notifies the object that it has been completely saved and points it to its new persisted state.

Synopsis

#include <urlmon.h>

HRESULT SaveCompleted(
        IMoniker * pmkNew,
        IBindCtx * pbc );

Description

Typically, the object will immediately bind to its persistent state through a call to pmkNew->BindToStorage method, requesting either the IStream() or IStorage() interface, as in IPersistMoniker::Load().

Parameters

pmkNew

[in] Pointer to the moniker for the object's new persistent state. This parameter can be NULL if the moniker to the object's new persistent state is the same as the previous moniker to the object's persistent state. This optimization is allowed only if there was a prior call to IPersistMoniker::Save() with the fRemember parameter set to TRUE, in which case the object need not rebind to pmkNew.

pbc

[in] Pointer to the bind context to use for any moniker binding during this method.

Return Values

S_OK

The operation was successful.

E_INVALIDARG

One or more parameters are invalid.

See Also

IPersistMoniker::Load(), IPersistMoniker::Save()

5.4.5    IRunnableObject

The IRunnableObject() interface enables a container to control the running of its embedded objects. In the case of an object implemented with a local server, calling launches the server's .EXE file. In the case of an object implemented with an in-process server, calling the Run() method causes the object .DLL file to transition into the running state.

When to Implement

Object handlers should implement IRunnableObject() to provide their containers with a way to run them and manage their running state. DLL object applications should implement IRunnableObject() to support silent updates of their objects.

When to Use

Containers call IRunnableObject() to determine if an embedded object is running, to force an object to run, to lock an object into the running state, or to inform an object handler whether its object is being run as either a simple embedding or as a link source.

Table 5-11:  IRunnableObject Methods in VTable Order

IUnknown() Methods Description
QueryInterface() Returns pointers to supported interfaces.
AddRef() Increments reference count.
Release() Decrements reference count.

Table 5-12:  IRunnableObject Methods

IRunnableObject() Methods Description
GetRunningClass() Returns CLSID of a running object.
Run() Forces an object to run.
IsRunning() Determines if an object is running.
LockRunning() Locks an object into running state.
SetContainedObject() Indicates that an object is embedded.

 

IRunnableObject::GetRunningClass()

NAME

IRunnableObject::GetRunningClass() - Returns the CLSID of a running object.

Synopsis

#include <objidl.h>

HRESULT GetRunningClass((
         LPCLSID lpClsid );

Description

If an embedded document was created by an application that is not available on the user's computer, the document, by a call to CoTreatAsClass(), may be able to display itself for editing by emulating a class that is supported on the user's machine. In this case, the CLSID returned by a call to IRunnableObject::GetRunningClass() will be that of the class being emulated, rather than the document's native class.

Parameters

lpClsid

[out] Pointer to the object's class identifier.

Return Values

This method supports the standard return values E_INVALIDARG and E_UNEXPECTED, as well as the following:

S_OK

CLSID was returned successfully.

See Also

CoTreatAsClass()  

IRunnableObject::IsRunning()

NAME

IRunnableObject::IsRunning() - Determines whether an object is currently in the running state.

Synopsis

#include <objidl.h>

BOOL IsRunning((
         );

Description

A container application could call IRunnableObject::IsRunning() when it needs to know if the server is immediately available.

An object handler could call IRunnableObject::IsRunning() when it wants to avoid conflicts with a running server or when the running server might have more up-to-date information.

OleIsRunning() is a helper function that conveniently repackages the functionality offered by IRunnableObject::IsRunning(). With the release of OLE 2.01, the implementation of OleIsRunning() was changed so that it calls QueryInterface(), asks for IRunnableObject(), and then calls IRunnableObject::IsRunning(). In other words, you can use the interface and the helper function interchangeably.

Return Values

TRUE

The object is in the running state.

FALSE

The object is not in the running state.

See Also

OleIsRunning()  

IRunnableObject::LockRunning()

NAME

IRunnableObject::LockRunning() - Locks an already running object into its running state or unlocks it from its running state.

Synopsis

#include <objidl.h>

HRESULT LockRunning((
        BOOL fLock,
        BOOL fLastUnlockCloses );

Description

Most implementations of IRunnableObject::LockRunning() call CoLockObjectExternal(). OleLockRunning() is a helper function that conveniently repackages the functionality offered by IRunnableObject::LockRunning(). With the release of OLE 2.01, the implementation of OleLockRunning() was changed to call QueryInterface(), ask for IRunnableObject(), and then call IRunnableObject::LockRunning(). In other words, you can use the interface and the helper function interchangeably.

Parameters

fLock

[in] TRUE locks the object into its running state. FALSE unlocks the object from its running state.

fLastUnlockCloses

[in] TRUE specifies that if the connection being released is the last external lock on the object, the object should close. FALSE specifies that the object should remain open until closed by the user or another process.

Return Values

This method supports the standard return values E_FAIL, E_INVALIDARG, E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK

If the value of fLock is TRUE, the object was successfully locked; if the value of fLock is FALSE, the object was successfully unlocked.

See Also

CoLockObjectExternal()  

IRunnableObject::Run()

NAME

IRunnableObject::Run() - Runs an object.

Synopsis

#include <objidl.h>

HRESULT Run((
        LPBC lpbc );

Description

Containers call IRunnableObject::Run() to force their objects to enter the running state. If the object is not already running, calling IRunnableObject::Run() can be an expensive operation, on the order of many seconds. If the object is already running, then this method has no effect on the object.

Notes to Callers

When called on a linked object that has been converted to a new class since the link was last activated, IRunnableObject::Run() may return OLE_E_CLASSDIFF.

OleRun is a helper function that conveniently repackages the functionality offered by IRunnableObject::Run(). With the release of OLE 2.01, the implementation of OleRun was changed so that it calls QueryInterface(), asks for IRunnableObject(), and then calls IRunnableObject::Run(). In other words, you can use the interface and the helper function interchangeably.

Notes to Implementors

The object should register in the running object table if it has a moniker assigned. The object should not hold any strong locks on itself; instead, it should remain in the unstable, unlocked state. The object should be locked when the first external connection is made to the object.

An embedded object must hold a lock on its embedding container while it is in the running state. The Default handler provided by OLE 2 takes care of locking the embedding container on behalf of objects implemented by an EXE object application.

Parameters

lpbc

[in] Pointer to the binding context of the run operation. May be NULL.

Return Values

This method supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK

The object was successfully placed in the running state.

See Also

OleRun  

IRunnableObject::SetContainedObject()

NAME

IRunnableObject::SetContainedObject() - Notifies an object that it is embedded in an OLE container, which ensures that reference counting is done correctly for containers that support links to embedded objects.

Synopsis

#include <objidl.h>

HRESULT SetContainedObject((
        BOOL fContained );

Description

The IRunnableObject::SetContainedObject() method enables a container to inform an object handler that it is embedded in the container, rather than acting as a link. This call changes the container's reference on the object from strong, the default for external connections, to weak. When the object is running visibly, this method is of little significance because the end user has a lock on the object. During a silent update of an embedded link source, however, the container should not be able to hold an object in the running state after the link has been broken. For this reason, the container's reference to the object must be weak.

Notes to Callers

A container application must call IRunnableObject::SetContainedObject() if it supports linking to embedded objects. It normally makes the call immediately after calling OleLoad() or OleCreate() and never calls the method again, even before it closes. Moreover, a container almost always calls this method with fContained set to TRUE. The use of this method with fContained set to FALSE is rare.

Calling IRunnableObject::SetContainedObject() is optional only when you know that the embedded object will not be referenced by any client other than the container. If your container application does not support linking to embedded objects; it is preferable, but not necessary, to call IRunnableObject::SetContainedObject().

OleSetContainedObject() is a helper function that conveniently repackages the functionality offered by IRunnableObject::SetContainedObject(). With the release of OLE 2.01, the implementation of OleSetContainedObject was changed to call QueryInterface(), ask for IRunnableObject(), and then call IRunnableObject::SetContainedObject(). In other words, you can use the interface and the helper function interchangeably.

Parameters

fContained

[in] TRUE specifies that the object is contained in an OLE container. FALSE indicates that it is not.

Return Values

This method supports the standard return values E_INVALIDARG, E_OUTOFMEMORY AND E_UNEXPECTED, as well as the following:

S_OK

Object has been marked as a contained embedding.

See Also

OleSetContainedObject(), OleNoteObjectVisible(), CoLockObjectExternal()

5.5    COM Library API Descriptions

 

CoGetMalloc()

NAME

CoGetMalloc() - Retrieves a pointer to the default COM task memory allocator (which supports the system implementation of the IMalloc() interface) so applications can call its methods to manage memory.

Synopsis

#include <objbase.h>

HRESULT CoGetMalloc((
        DWORD dwMemContext,
        LPMALLOC * ppMalloc );

Description

The pointer to the IMalloc() interface pointer received through the ppMalloc parameter cannot be used from a remote process; each process must have its own allocator.

Parameters

dwMemContext

[in] Reserved; value must be 1.

ppMalloc

[out] Address of IMalloc* pointer variable that receives the interface pointer to the memory allocator.

Return Values

This function supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following:

S_OK

Indicates the allocator was retrieved successfully.

See Also

IMalloc(), CoTaskMemAlloc()  

CoInitialize()

NAME

CoInitialize() - Initializes COM library on the current apartment and identifies the concurrency model as single-thread apartment (STA). Applications must initialize the COM library before they can call COM library functions other than CoGetMalloc() and memory allocation functions. New applications should call CoInitializeEx() instead of CoInitialize().

Synopsis

#include <objbase.h>

HRESULT CoInitialize((
        LPVOID pvReserved );

Description

CoInitializeEx() provides the same functionality as CoInitialize() and also provides a parameter to explicitly specify the apartment's concurrency model. CoInitialize() calls CoInitializeEx() and specifies the concurrency model as single-thread apartment. Applications developed today should call CoInitializeEx() rather than CoInitialize().

You need initialize the COM library on an apartment before you call any of the library functions except CoGetMalloc(), to get a pointer to the standard allocator, and the memory allocation functions.

Typically, the COM library is initialized on an apartment only once. Subsequent calls will succeed, as long as they do not attempt to change the concurrency model, but will return S_FALSE. To close the COM library gracefully, each successful call to CoInitialize() or CoInitializeEx(), including those that return S_FALSE, must be balanced by a corresponding call to CoUninitialize().

Once the concurrency model for an apartment is set, it cannot be changed. A call to CoInitialize() on an apartment that was previously initialized as multithreaded will fail and return RPC_E_CHANGED_MODE.

Parameters

pvReserved

[in] Reserved; must be NULL.

Return Values

This function supports the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following:

S_OK

The COM library was initialized successfully on this apartment.

S_FALSE

The COM library is already initialized on this apartment.

RPC_E_CHANGED_MODE

A previous call to CoInitializeEx() specified the concurrency model for this apartment as multithread apartment (MTA).

See Also

CoInitializeEx(), CoUninitialize(), OleInitialize, Processes and Threads  

CoInitializeEx()

NAME

CoInitializeEx() - Initializes the COM library for use by the current apartment and specifies the apartment's concurrency model.

Synopsis

#include <objbase.h>

HRESULT CoInitializeEx((
        void * pvReserved,
        DWORD dwCoInit );

Description

If neither concurrency model is specified by the dwCoInit parameter, the default is COINIT_APARTMENTTHREADED.

Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. You would typically implement some form of concurrency control in a multithreaded object's code using Win32 synchronization primitives such as critical sections, semaphores, or mutexes to protect the object's data.

Objects created in a single-threaded apartment (STA) receive method calls only from their apartment's thread, so calls are serialized and arrive only at message-queue boundaries (PeekMessage, SendMessage).

Apartments must call CoInitializeEx() or CoInitialize() before calling any other COM library functions except CoGetMalloc() and other memory allocation calls (CoTaskMemAlloc(), CoTaskMemFree(), CoTaskMemReAlloc, and the IMalloc() methods on the task allocator supplied by CoGetMalloc()).

CoInitializeEx() provides the same functionality as CoInitialize() and also provides a parameter to explicitly specify the thread's concurrency model. The current implementation of CoInitialize() calls CoInitializeEx() and specifies the concurrency model as single-thread apartment. Applications developed today should call CoInitializeEx() rather than CoInitialize().

Typically, CoInitializeEx() is called only once by each apartment in the process that uses the COM library. For a multithread apartment, one call is sufficient for all threads in the apartment. Multiple calls to CoInitializeEx() by the same thread are allowed as long as they pass the same concurrency flag, but subsequent valid calls return S_FALSE. To close the library gracefully, each successful call to CoInitialize() or CoInitializeEx(), including calls that return S_FALSE, must be balanced by a corresponding call to CoUninitialize().

Once the concurrency model for an apartment is set, it cannot be changed. A call to CoInitializeEx() on an apartment that was previously initialized with a different concurrency model will fail and return RPC_E_CHANGED_MODE. Because COM technologies are not thread-safe, the OleInitialize function calls CoInitializeEx() with the COINIT_APARTMENTTHREADED flag. As a result, an apartment that is initialized for multi-threaded object concurrency cannot use the features enabled by OleInitialize.

Parameters

pvReserved

[in] Reserved; must be NULL.

dwCoInit

Flags specifying the concurrency model and initialization options for the thread. Values for this parameter are taken from the COINIT enumeration, except that the COINIT_APARTMENTTHREADED and COINIT_MULTITHREADED flags cannot both be set.

Return Values

This function supports the standard return values E_INVALIDARG, E_OUTOFMEMORY, and E_UNEXPECTED, as well as the following:

S_OK

The COM library was initialized successfully.

S_FALSE

The COM library is already initialized.

RPC_E_CHANGED_MODE

A previous call to CoInitializeEx() specified a different concurrency model for this thread.

See Also

COINIT, CoInitialize(), Processes and Threads  

CoTaskMemAlloc()

NAME

CoTaskMemAlloc() - Allocates a block of task memory in the same way that IMalloc::Alloc() does.

Synopsis

#include <objbase.h>

LPVOID CoTaskMemAlloc((
        ULONG cb );

Description

The CoTaskMemAlloc() function uses the default allocator to allocate a memory block in the same way that IMalloc::Alloc() does. It is not necessary to call the CoGetMalloc() function before calling CoTaskMemAlloc().

The initial contents of the returned memory block are undefined - there is no guarantee that the block has been initialized. The allocated block may be larger than cb bytes because of the space required for alignment and for maintenance information.

If cb is zero, CoTaskMemAlloc() allocates a zero-length item and returns a valid pointer to that item. If there is insufficient memory available, CoTaskMemAlloc() returns NULL.

Applications should always check the return value from this method, even when requesting small amounts of memory, because there is no guarantee the memory will be allocated.

Parameters

cb

[in] Size, in bytes, of the memory block to be allocated.

Return Values

Allocated memory block

Memory block allocated successfully.

NULL

Insufficient memory available.

See Also

IMalloc::Alloc(), CoGetMalloc(), CoTaskMemFree(), CoTaskMemRealloc()  

CoTaskMemFree()

NAME

CoTaskMemFree() - Frees a block of task memory previously allocated through a call to the CoTaskMemAlloc() or CoTaskMemRealloc() function.

Synopsis

#include <objbase.h>

void CoTaskMemFree((
        void pv );

Description

The CoTaskMemFree() function, using the default COM allocator, frees a block of memory previously allocated through a call to the CoTaskMemAlloc() or CoTaskMemRealloc() function.

The number of bytes freed equals the number of bytes that were originally allocated or reallocated. After the call, the memory block pointed to by pv is invalid and can no longer be used.

The pv parameter can be NULL, in which case this method has no effect.

Parameters

pv

[in] Pointer to the memory block to be freed.

See Also

CoTaskMemAlloc(), CoTaskMemRealloc(), CoGetMalloc(), IMalloc::Free()  

CoTaskMemRealloc()

NAME

CoTaskMemRealloc() - Changes the size of a previously allocated block of task memory.

Synopsis

#include <objbase.h>

LPVOID CoTaskMemRealloc((
        LPVOID pv,
        ULONG cb );

Description

The CoTaskMemRealloc() function changes the size of a previously allocated memory block in the same way that IMalloc::Realloc() does. It is not necessary to call the CoGetMalloc() function to get a pointer to the COM allocator before calling CoTaskMemRealloc().

The pv argument points to the beginning of the memory block. If pv is NULL, CoTaskMemRealloc() allocates a new memory block in the same way as the CoTaskMemAlloc() function. If pv is not NULL, it should be a pointer returned by a prior call to CoTaskMemAlloc().

The cb argument specifies the size (in bytes) of the new block. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a different memory location, the pointer returned by CoTaskMemRealloc() is not guaranteed to be the pointer passed through the pv argument. If pv is not NULL and cb is zero, then the memory pointed to by pv is freed.

CoTaskMemRealloc() returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough memory available to expand the block to the given size. In the first case, the original block is freed; in the second, the original block is unchanged.

The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.

Parameters

pv

[in] Pointer to the memory block to be reallocated. It can be a NULL pointer, as discussed in the Remarks.

cb

[in] Size, in bytes, of the memory block to be reallocated. It can be zero, as discussed in the following remarks.

Return Values

Reallocated memory block

Memory block successfully reallocated.

NULL

Insufficient memory or cb is zero and pv is not NULL.

See Also

CoTaskMemAlloc(), CoTaskMemFree(), CoGetMalloc(), IMalloc::Realloc()  

CoUninitialize()

NAME

CoUninitialize() - Closes the COM library on the current apartment, unloads all DLLs loaded by the apartment, and frees any resources that it maintains, and forces all RPC connections on the apartment to close.

Synopsis

#include <objbase.h>

void CoUninitialize((
         );

Description

The CoInitialize() and CoUninitialize() calls must call CoUninitialize() once for each successful call it has made to CoInitialize() or CoInitializeEx(). Only the CoUninitialize() call corresponding to the CoInitialize() call that initialized the library can close it.

Calls to OleInitialize must be balanced by calls to OleUnitialize. The OleUninitialize function calls CoUninitialize() internally, so applications that call OleUninitialize do not also need to call CoUninitialize().

CoUninitialize() should be called on application shutdown, as the last call made to the COM library after the application hides its main windows and falls through its main message loop. If there are open conversations remaining, CoUninitialize() starts a modal message loop and dispatches any pending messages from the containers or server for this COM application. By dispatching the messages, CoUninitialize() ensures that the application does not quit before receiving all of its pending messages. Non-COM messages are discarded.

See Also

CoInitialize(), CoInitializeEx()  

CoRegisterMallocSpy()

NAME

CoRegisterMallocSpy() - Registers an implementation of the IMallocSpy() interface in COM, thereafter requiring COM to call its wrapper methods around every call to the corresponding IMalloc() method. IMallocSpy() is defined in COM to allow developers to debug memory allocations.

Synopsis

#include <objbase.h>

HRESULT CoRegisterMallocSpy((
        LPMALLOCSPY pMallocSpy );

Description

The CoRegisterMallocSpy() function registers the IMallocSpy() object, which is used to debug calls to IMalloc() methods. The function calls QueryInterface() on the pointer pMallocSpy for the interface IID_IMallocSpy. This is to ensure that pMallocSpy really points to an implementation of IMallocSpy(). By the rules of COM, it is expected that a successful call to QueryInterface() has added a reference (through the AddRefmethod) to the IMallocSpy() object. That is, CoRegisterMallocSpy() does not directly call AddRef() on pMallocSpy, but fully expects that the QueryInterface() call will.

When the IMallocSpy() object is registered, whenever there is a call to one of the IMalloc() methods, COM first calls the corresponding IMallocSpy() pre-method. Then, after executing the IMalloc() method, COM calls the corresponding IMallocSpy() post-method. For example, whenever there is a call to IMalloc::Alloc(), from whatever source, COM calls IMallocSpy::PreAlloc(), calls IMalloc::Alloc(), and after that allocation is completed, calls IMallocSpy::PostAlloc().

Parameters

pMallocSpy

[in] Pointer to an instance of the IMallocSpy() implementation.

Return Values

This function supports the standard return value E_INVALIDARG, as well as the following:

S_OK

The IMallocSpy() object is successfully registered.

CO_E_OBJISREG

There is already a registered spy.

See Also

IMallocSpy(), CoRevokeMallocSpy(), CoGetMalloc()  

CoRevokeMallocSpy()

NAME

CoRevokeMallocSpy() - Revokes a registered IMallocSpy() object.

Synopsis

#include <objbase.h>

HRESULT CoRevokeMallocSpy((
         );

Description

The IMallocSpy() object is released when it is revoked. This release corresponds to the call to IUnknown::AddRef() in the implementation of the QueryInterface() function by the CoRegisterMallocSpy() function. The implementation of the IMallocSpy() interface should then do any appropriate cleanup.

If the return code is E_ACCESSDENIED, there are still outstanding allocations that were made while the spy was active. In this case, the registered spy cannot be revoked at this time because it may have attached arbitrary headers and/or trailers to these allocations that only the spy knows about. Only the spy's PreFree (or PreRealloc) method knows how to account for these headers and trailers. Before returning E_ACCESSDENIED, CoRevokeMallocSpy() notes internally that a revoke is pending. When the outstanding allocations have been freed, the revoke proceeds automatically, releasing the IMallocSpy() object. Thus, it is necessary to call CoRevokeMallocSpy() only once for each call to CoRegisterMallocSpy(), even if E_ACCESSDENIED is returned.

Return Values

S_OK

The IMallocSpy() object is successfully revoked.

CO_E_OBJNOTREG

No spy is currently registered.

E_ACCESSDENIED

Spy is registered but there are outstanding allocations (not yet freed) made while this spy was active.

See Also

IMallocSpy(), CoRegisterMallocSpy(), CoGetMalloc()  

CLSIDFromProgID()

NAME

CLSIDFromProgID() - Looks up a CLSID in the registry, given a ProgID.

Synopsis

#include <objbase.h>

HRESULT CLSIDFromProgID((
        LPCOLESTR lpszProgID,
        LPCLSID pclsid );

Description

Given a ProgID, CLSIDFromProgID() looks up its associated CLSID in the registry. If the ProgID cannot be found in the registry, CLSIDFromProgID() creates an OLE 1 CLSID for the ProgID and a CLSID entry in the registry. Because of the restrictions placed on OLE 1 CLSIDs, CLSIDFromProgID() and CLSIDFromString() are the only two functions that can be used to generate a CLSID for an OLE 1 object.

Parameters

lpszProgID

[in] Pointer to the ProgID whose CLSID is requested.

pclsid

[out] Pointer to the retrieved CLSID on return.

Return Values

S_OK

The CLSID was retrieved successfully.

CO_E_CLASSSTRING

The registered CLSID for the ProgID is invalid.

REGDB_E_WRITEREGDB

An error occurred writing the CLSID to the registry. See Description.

See Also

ProgIDFromCLSID()  

CLSIDFromString()

NAME

CLSIDFromString() - Converts a string generated by the StringFromCLSID() function back into the original CLSID.

Synopsis

#include <objbase.h>

HRESULT CLSIDFromString((
        LPOLESTR lpsz,
        LPCLSID pclsid );

Description

Because of the restrictions placed on OLE 1 CLSID values, CLSIDFromProgID() and CLSIDFromString() are the only two functions that can be used to generate a CLSID for an OLE 1 object.

Parameters

lpsz

[in] Pointer to the string representation of the CLSID.

pclsid

[out] Pointer to the CLSID on return.

Return Values

This function supports the standard return value E_INVALIDARG, as well as the following:

NOERROR

The CLSID was obtained successfully.

CO_E_CLASSTRING

The class string was improperly formatted.

REGDB_E_WRITEREGDB

The CLSID corresponding to the class string was not found in the registry.

See Also

CLSIDFromProgID(), StringFromCLSID()  

CoCreateGuid()

NAME

CoCreateGuid() - Creates a GUID, a unique 128-bit integer used for CLSIDs and interface identifiers.

Synopsis

#include <objbase.h>

HRESULT CoCreateGuid((
        GUID * pguid );

Description

The CoCreateGuid() function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use the CoCreateGuid() function when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment. To a very high degree of certainty, this function returns a unique value--no other invocation, on the same or any other system (networked or not), should return the same value.

Parameters

pguid

[out] Pointer to the requested GUID on return.

Return Values

S_OK

The GUID was successfully created.

Win32 errors are returned by UuidCreate but wrapped as an HRESULT.

See Also

UuidCreate <(documented in the RPC Programmer's Guide and Reference)>  

CoDosDateTimeToFileTime()

NAME

CoDosDateTimeToFileTime() - Converts the MS-DOS representation of the time and date to a FILETIME structure, which Win32 uses to determine the date and time.

Synopsis

#include <objbase.h>

BOOL CoDosDateTimeToFileTime((
        WORD nDosDate,
        WORD nDosTime,
        FILETIME * lpFileTime );

Description

The FILETIME structure and the CoDosDateTimeToFileTime() and CoFileTimeToDosDateTime() functions are part of the Win32 API definition. They are provided for compatibility in all OLE implementations, but are redundant on Win32 platforms.

MS-DOS records file dates and times as packed 16-bit values. An MS-DOS date has the following format:

1.  MS-DOS Date Format

Bits Contents
0-4 Days of the month (1-31).
5-8 Months (1 = January, 2 = February, and so forth).
9-15 Year offset from 1980 (add 1980 to get actual year).

An MS-DOS time has the following format:

2.  MS-DOS Time Format

Bits Contents
0-4 Seconds divided by 2.
5-10 Minutes (0-59).
11-15 Hours (0-23 on a 24-hour clock).

Parameters

nDosDate

[in] 16-bit MS-DOS date.

nDosTime

[in] 16-bit MS-DOS time.

lpFileTime

[out] Pointer to the FILETIME structure.

Return Values

TRUE

The FILETIME structure was created successfully.

FALSE

The FILETIME structure was not created successfully, probably because of invalid arguments.

See Also

CoFileTimeToDosDateTime(), CoFileTimeNow()  

CoFileTimeNow()

NAME

CoFileTimeNow() - Returns the current time as a FILETIME structure.

Synopsis

#include <objbase.h>

HRESULT CoFileTimeNow((
        FILETIME * lpFileTime );

Parameters

lpFileTime

[out] Pointer to return the FILETIME structure.

Return Values

S_OK

The current time was converted to a FILETIME structure.

See Also

CoDosDateTimeToFileTime(), CoFileTimeToDosDateTime()  

CoFileTimeToDosDateTime()

NAME

CoFileTimeToDosDateTime () - Converts a FILETIME into MS-DOS date and time values.

Synopsis

#include <objbase.h>

BOOL CoFileTimeToDosDateTime((
        FILETIME * lpFileTime,
        LPWORD lpDosDate,
        LPWORD lpDosTime );

Description

This is the inverse of the operation provided by the CoDosDateTimeToFileTime() function.

Parameters

lpFileTime

[in] Pointer to the FILETIME structure to be converted.

lpDosDate

[out] Pointer to the 16-bit MS-DOS date.

lpDosTime

[out] Pointer to the 16-bit MS-DOS time.

Return Values

TRUE

The FILETIME structure was converted successfully.

FALSE

The FILETIME structure was not converted successfully.

See Also

CoDosDateTimeToFileTime(), CoFileTimeNow()  

CoGetCurrentProcess()

NAME

CoGetCurrentProcess() - Returns a value that is unique to the current thread. It can be used to avoid PROCESSID reuse problems.

Synopsis

#include <objbase.h>

DWORD CoGetCurrentProcess((
         );

Description

The CoGetCurrentProcess function returns a value that is effectively unique, because it is not used again until 232 more threads have been created on the current workstation or until the workstation is rebooted.

Using the value returned from a call to CoGetCurrentProcess() can help you maintain tables that are keyed by threads or in uniquely identifying a thread to other threads or processes.

Using the value returned by CoGetCurrentProcess() is more robust than using the HTASK task handle value returned by the Win32 function GetCurrentTask, because Windows task handles can be reused relatively quickly when a window's task dies.

Return Values

DWORD value

Unique value for the current thread that can be used to avoid PROCESSID reuse problems.

 

IIDFromString()

NAME

IIDFromString() - Converts a string generated by the StringFromIID() function back into the original interface identifier (IID).

Synopsis

#include <objbase.h>

WINOLEAPI IIDFromString((
        LPOLESTR lpsz,
        LPIID lpiid );

Description

The function converts the interface identifier in a way that guarantees different interface identifiers will always be converted to different strings.

Parameters

lpsz

[in] Pointer to the string representation of the IID.

lpiid

[out] Pointer to the requested IID on return.

Return Values

This function supports the standard return values E_INVALIDARG and E_OUTOFMEMORY, as well as the following:

S_OK

The string was successfully converted.

See Also

StringFromIID()  

IsEqualGUID()

NAME

IsEqualGUID() - Determines whether two GUIDs are equal.

Synopsis

#include <objbase.h>

BOOL IsEqualGUID((
        REFGUID rguid1,
        REFGUID rguid2 );

Description

IsEqualGUID() is used by the IsEqualCLSID() and IsEqualIID() functions.

Parameters

rguid1

[in] GUID to compare to rguid2.

rguid2

[in] GUID to compare to rguid1.

Return Values

TRUE

The GUIDs are equal.

FALSE

The GUIDs are not equal.

See Also

IsEqualCLSID(), IsEqualIID  

IsEqualCLSID()

NAME

IsEqualCLSID() - Determines whether two CLSIDs are equal.

Synopsis

#include <winerror.h>

BOOL IsEqualCLSID((
        REFCLSID rclsid1,
        REFCLSID rclsid2 );

Parameters

rclsid1

[in] CLSID to compare to rclsid2.

rclsid2

[in] CLSID to compare to rclsid1.

Return Values

TRUE

The CLSIDs are equal.

FALSE

The CLSIDs are not equal.

See Also

IsEqualGUID(), IsEqualIID  

IsEqualIID()

NAME

IsEqualIID() - Determines whether two interface identifiers are equal.

Synopsis

#include <winerror.h>

BOOL IsEqualIID((
        REFGUID riid1,
        REFGUID riid2 );

Parameters

riid1

[in] Interface identifier to compare with riid2.

riid2

[in] Interface identifier to compare with riid1.

Return Values

TRUE

The interface identifiers are equal.

FALSE

The interface identifiers are not equal.

See Also

IsEqualGUID(), IsEqualCLSID  

GetRunningObjectTable()

NAME

GetRunningObjectTable() - Supplies a pointer to the IRunningObjectTable() interface on the local Running Object Table (ROT).

Synopsis

#include <objbase.h>

WINOLEAPI GetRunningObjectTable((
        DWORD reserved,
        LPRUNNINGOBJECTTABLE * pprot );

Description

Each workstation has a local ROT that maintains a table of the objects that have been registered as running on that machine. This function returns an IRunningObjectTable() interface pointer, which provides access to that table.

Moniker providers, which hand out monikers that identify objects so they are accessible to others, should call GetRunningObjectTable(). Use the interface pointer returned by this function to register your objects when they begin running, to record the times that those objects are modified, and to revoke their registrations when they stop running. See the IRunningObjectTable() interface for more information.

Compound-document link sources are the most common example of moniker providers. These include server applications that support linking to their documents (or portions of a document) and container applications that support linking to embeddings within their documents. Server applications that do not support linking can also use the ROT to cooperate with container applications that support linking to embeddings.

If you are implementing the IMoniker() interface to write a new moniker class, and you need an interface pointer to the ROT, call IBindCtx::GetRunningObjectTable() rather than the GetRunningObjectTable() function. This allows future implementations of the IBindCtx() interface to modify binding behavior.

Parameters

reserved

[in] Reserved for future use; must be zero.

pprot

[out] Address of IRunningObjectTable* pointer variable that receives the interface pointer to the local ROT. When the function is successful, the caller is responsible for calling IUnknown::Release() on the interface pointer. If an error occurs, pprot is undefined.

Return Values

This function supports the standard return value E_UNEXPECTED, as well as the following:

S_OK

An IRunningObjectTable() pointer was successfully returned.

See Also

IBindCtx::GetRunningObjectTable(), IMoniker, IRunningObjectTable()  

ProgIDFromCLSID()

NAME

ProgIDFromCLSID() - Retrieves the ProgID for a given CLSID.

Synopsis

#include <objbase.h>

WINOLEAPI ProgIDFromCLSID((
        REFCLSID clsid,
        LPOLESTR * lplpszProgID );

Description

Every COM object class listed in the Insert Object dialog box must have a programmatic identifier (ProgID), a string that uniquely identifies a given class, stored in the registry. In addition to determining the eligibility for the Insert Object dialog box, the ProgID can be used as an identifier in a macro programming language to identify a class. Finally, the ProgID is also the class name used for an object of an COM class that is placed in an OLE 1 container.

The ProgIDFromCLSID function uses entries in the registry to do the conversion. COM application authors are responsible for ensuring that the registry is configured correctly in the application's setup program.

The ProgID string must be different than the class name of any OLE 1 application, including the OLE 1 version of the same application, if there is one. In addition, a ProgID string must not contain more than 39 characters, start with a digit, or, except for a single period, contain any punctuation (including underscores).

The ProgID must never be shown to the user in the user interface.

Call the CLSIDFromProgID() function to find the CLSID associated with a given ProgID. CLSIDs can be freed with the task allocator (refer to the CoGetMalloc() function).

Parameters

clsid

[in] Specifies the CLSID for which the ProgID is requested.

lplpszProgID

[out] Address of LPOLESTR pointer variable that receives a pointer to the ProgID string.

Return Values

S_OK

The ProgID was returned successfully.

REGDB_E_CLASSNOTREG

Class not registered in the registry.

REGDB_E_READREGDB

Error reading registry.

See Also

CLSIDFromProgID()  

StringFromCLSID()

NAME

StringFromCLSID() - Converts a CLSID into a string of printable characters. Different CLSIDs always convert to different strings.

Synopsis

#include <objbase.h>

WINOLEAPI StringFromCLSID((
        REFCLSID rclsid,
        LPOLESTR * ppsz );

Description

The StringFromCLSID function calls the StringFromGuid2 function to convert a globally unique identifier (GUID) into a string of printable characters.

Parameters

rclsid

[in] CLSID to be converted.

ppsz

[out] Address of LPOLESTR pointer variable that receives a pointer to the resulting string.

Return Values

This function supports the standard return value E_OUTOFMEMORY; as well as the following:

S_OK

Indicates the CLSID was successfully converted and returned.

See Also

CLSIDFromString(), StringFromGuid2  

StringFromGUID2()

NAME

StringFromGUID2() - Converts a globally unique identifier (GUID) into a string of printable characters.

Synopsis

#include <objbase.h>

StringFromGUID2(
        REFGUID rguid,
        LPOLESTR lpsz,
        int cbMax );

Description

The string that the lpsz parameter receives has a format like that of the following sample:

{c200e360-38c5-11ce-ae62-08002b2b79ef}

where the successive fields break the GUID into the form DWORD-WORD-WORD-WORD-WORD.DWORD covering the 128-bit GUID. The string includes enclosing braces, which are a COM convention.

Parameters

rguid

[in] Interface identifier to be converted.

lpsz

[out] Pointer to the resulting string on return.

cbMax

[in] Maximum size the returned string is expected to be.

Return Values

0 (zero)

Buffer is too small for returned string.

Non-zero value

The number of characters in the returned string, including the null terminator.

See Also

StringFromCLSID()  

StringFromIID()

NAME

StringFromIID() - Converts an interface identifier into a string of printable characters.

Synopsis

#include <objbase.h>

WINOLEAPI StringFromIID((
        REFIID rclsid,
        LPOLESTR * lplpsz );

Description

The string returned by the function is freed in the standard way, using the task allocator (refer to the CoGetMallocfunction()).

Parameters

rclsid

[in] Interface identifier to be converted.

lplpsz

[out] Address of LPOLESTR pointer variable that receives a pointer to the resulting string.

Return Values

This function supports the standard return value E_OUTOFMEMORY; as well as the following:

S_OK

The character string was successfully returned.

See Also

IIDFromString(), CoGetMalloc()  

CoRegisterMessageFilter()

NAME

CoRegisterMessageFilter() - Registers with OLE the instance of an EXE application's interface, which is to be used for handling concurrency issues. DLL object applications cannot register a message filter.

Synopsis

#include <objbase.h>

HRESULT CoRegisterMessageFilter((
        LPMALLOCSPY lpMessageFilter,
        LPMESSAGEFILTER * lplpMessageFilter );

Parameters

lpMessageFilter

[in] Pointer to the IMessageFilter() interface on the message filter supplied by the application. Can be NULL, indicating that the current IMessageFilter() registration should be revoked.

lplpMessageFilter

[out] Address of IMessageFilter()* pointer variable that receives the interface pointer to the previously registered message filter. If there was no previously registered message filter, the value of *lplpMessageFilter is NULL. The value contained in the output variable is rarely NULL, however, containing instead a pointer to the default message filter.

Return Values

S_OK

The IMessageFilter() instance registered or revoked successfully.

S_FALSE

Error registering or revoking IMessageFilter() instance.

5.6    COM Library Enumeration Definitions

 

COINIT()

NAME

COINIT() - A set of values from the COINIT enumeration is passed as the dwCoInit parameter to CoInitializeEx(). This value determines the concurrency model used for incoming calls to objects created by this thread. This concurrency model can be either apartment-threaded or multi-threaded.

Synopsis

#include <objbase.h>

COINIT( );

The COINIT enumeration is defined as follows:

typedef enum tagCOINIT{
  COINIT_APARTMENTTHREADED = 0x2,  // Apartment model
  COINIT_MULTITHREADED     = 0x0,  // COM calls objects on any thread.
} COINIT;

Description

When a thread is initialized through a call to CoInitializeEx(), you choose whether to initialize it as apartment-threaded or multi-threaded by designating one of the members of COINIT as its second parameter. This designates how incoming calls to any object created by that thread are handled, that is, the object's concurrency.

Apartment-threading, while allowing for multiple threads of execution, serializes all incoming calls by requiring that calls to methods of objects created by this thread always run on the same thread--the apartment/thread that created them. In addition, calls can arrive only at message-queue boundaries (i.e., only during a PeekMessage, SendMessage, DispatchMessage, etc.). Because of this serialization, it is not typically necessary to write concurrency control into the code for the object, other than to avoid calls to PeekMessage and SendMessage during processing that must not be interrupted by other method invocations or calls to other objects in the same apartment/thread.

Multi-threading (also called free-threading) allows calls to methods of objects created by this thread to be run on any thread. There is no serialization of calls--many calls may occur to the same method or to the same object or simultaneously. Multi-threaded object concurrency offers the highest performance and takes the best advantage of multi-processor hardware for cross-thread, cross-process, and cross-machine calling, since calls to objects are not serialized in any way. This means, however, that the code for objects must enforce its own concurrency model, typically through the use of Win32 synchronization primitives, such as critical sections, semaphores, or mutexes. In addition, because the object doesn't control the lifetime of the threads that are accessing it, no thread-specific state may be stored in the object (in Thread-Local-Storage).

Elements

COINIT_MULTITHREADED

Initializes the thread for multi-threaded object concurrency (see Description).

COINIT_APARTMENTTHREADED

Initializes the thread for apartment-threaded object concurrency (see Description).

See Also

CoInitializeEx(), Processes and Threads