分析 API 方法约定
本主题讨论探查器回调返回值和调用方分配的缓冲区。
回调返回值
探查器以 HRESULT 的形式为公共语言运行时 (CLR) 引发的每个通知返回一个状态值。 此状态值可能是 S_OK 或 E_FAIL。 目前,运行时会忽略每个回调(ICorProfilerCallback::ObjectReferences 方法除外)中的状态值。
调用方分配的缓冲区
接受调用方分配的缓冲区的 ICorProfilerInfo 方法(例如,GetAppDomainInfo 方法)通常符合以下签名:
HRESULT GetBuffer
(
[in] /* Some query information (for example, a name).*/,
[in] ULONG32 cBufferSizeStart,
[out] ULONG32 *pcBufferMax,
[out] /* TYPE */ InfoBuffer[]
);
这些方法始终按如下方式运行:
cBufferSizeStart 参数指定缓冲区中分配的元素数目。 此值表示由此方法的调用方分配的缓冲区的大小。
pcBufferMax 参数设置为可用元素的总数。 该方法返回后,pcBufferMax 将设置为原本应该返回的最大元素数目,而不是实际返回的元素数目。 因此,pcBufferMax 与调用方分配的缓冲区的实际大小无关。
InfoBuffer 参数指定调用方分配的缓冲区。 它由此方法的调用方创建。 其大小由 cBufferSizeStart 指定。 该方法返回后,此缓冲区中将填充尽可能多的元素。 可用的元素可能比可放入缓冲区中的元素多。 如果 InfoBuffer 为 null,则 cBufferSizeStart 必须为 0。 如果返回了任何元素,则该方法返回 S_OK,并将 pcBufferMax 设置为可用元素的总数。
可采用两种方法来处理调用方分配的缓冲区:
单遍方法:分配一个您认为大小足以包含所有返回的元素的缓冲区。 如果缓冲区证实太小,要准备好重新分配缓冲区。 否则,数据将可能被截断。
双遍方法:以交替方式调用方法两次。 第一次使用长度为零的 InfoBuffer 参数调用以获取正确的缓冲区大小。 然后,将缓冲区大小设置为 pcBufferMax 中返回的值,并再次调用函数。
第一种方法更快,并可避免动态分配。 但是,如果缓冲区大小不足以包含信息,您可能需要重新分配缓冲区。
第二种方法较慢,因为它牵涉到两次调用和动态分配。 例如,假定请求的查询信息针对的是应用程序域的名称。 此方法返回后,您必须验证 InfoBuffer 是否足够大以包含应用程序域的完整名称。 为此,请将 pcBufferMax 指向的值与 cBufferSizeStart 参数的值进行比较。 如果 pcBufferMax 指向大于 cBufferSizeStart 的值,请分配更大的 InfoBuffer 缓冲区,用新的、更大的大小更新 cBufferSizeStart,然后再次调用该方法。
可选的输出参数
在分析 API 中,所有输出参数(在方法语法中由 [out] 指定)都是可选的,除非方法只有一个输出参数。 探查器对于自己不关注的所有输出参数传递 Null。 探查器还必须为与输出参数关联的任何输入参数传递一致的值。 例如,如果 Null 输出参数表示要用数据填充的缓冲区,则指定缓冲区大小的输入参数必须设置为 0。