Caller-Allocated Buffers in the Profiling API

ICorProfilerInfo methods that take caller-allocated buffers typically conform to the following signature.

HRESULT GetBuffer
(
    [in]  /* Some query information (for example, a name).*/,
    [in]  ULONG32 cBufferSizeStart,
    [out] ULONG32 *pcBufferMax,
    [out] /* TYPE */ InfoBuffer[] 
);

These methods always behave as follows:

  • The cBufferSizeStart parameter specifies the number of elements allocated in the buffer. This value represents the size of the buffer, which is allocated by the caller of this method.

  • The pcBufferMax parameter is set to the total number of available elements. After the method returns, pcBufferMax is set to the maximum number of elements that could have been returned instead of the number of elements that actually were returned. So, pcBufferMax is independent of the actual size of the caller-allocated buffer.

  • The InfoBuffer parameter specifies the caller-allocated buffer. It is created by the caller of this method. Its size is specified by cBufferSizeStart. After the method returns, this buffer will be filled with as many elements as possible. There may be more elements available than will fit into the buffer. If InfoBuffer is null, cBufferSizeStart must be 0. If any elements are returned, the method returns S_OK and sets pcBufferMax to the total number of elements available.

Remarks

There are two ways to work with caller-allocated buffers:

  • Single-pass method: Allocate a buffer that you expect will be large enough to contain all the returned elements. Be prepared to reallocate the buffer if it proves to be too small. Otherwise, data truncation may occur.

  • Double-pass method: Alternatively, call the method two times. First call with a zero-length InfoBuffer parameter to obtain the correct buffer size. Then set the buffer size to the value returned in pcBufferMax and call the function again.

The first method is faster and avoids dynamic allocation. However, you may need to reallocate the buffer if it is not large enough to contain the information.

The second method is slower because it involves two calls and dynamic allocation. For example, let's assume that the requested query information was for an application domain's name. After this method returns, you must verify that InfoBuffer was large enough to contain the full name of the application domain. To do this, compare the value that pcBufferMax points to with the value of the cBufferSizeStart parameter. If pcBufferMax points to a value that is larger than cBufferSizeStart, allocate a larger InfoBuffer buffer, update cBufferSizeStart with the new, larger size, and call the method again.

See Also

Other Resources

Common Features in the Profiling API

Profiling Overview

Profiling (Unmanaged API Reference)