复杂类型定义的语法是什么?

Windows 事件跟踪 (ETW) 定义了多个要在跟踪函数中使用的简单和复杂类型。 这些类型在 Defaultwpp.ini 文件中声明。 但是,可以创建自己的自定义配置文件,并指示 WPP 使用它。

复杂数据类型DEFINE_CPLX_TYPE的格式如下所示:

DEFINE_CPLX_TYPE(TypeName, HelperMacroName, ArgumentType, WppMofType,"WppMofFormat", TypeSignature, Priority, Slots);

例如:

DEFINE_CPLX_TYPE(.*ls, WPP_LOGXWCS, const xwcs_t&, ItemPWString,"s", _xwcs_t_, 0, 2);

设置元素格式

TypeName
WPP 使用此字段来标识复杂类型。 例如 .*ls

HelperMacroName
一个帮助程序宏,用于将参数转换为长度/地址对格式的可变长度数组。 TraceMessage 函数需要此格式才能用于其变量参数列表中的每个条目。

若要正确设置参数的格式,必须在帮助程序宏的定义中使用 WPP_LOGPAIR 宏,如以下示例所示:

#define HelperMacroName(x) WPP_LOGPAIR(length, x)

注意 根据要实现的跟踪逻辑,可能需要使用多个WPP_LOGPAIR宏来定义宏。

参数类型
指示 TypeName 类型的参数可以接受的值。 例如, const xwcs_t&

WppMofType
指定由 WPP 预处理器识别 (MOF) 类型的托管对象格式

WppMofFormat
指定 WPP 预处理器可识别的格式说明符,如“s”。

TypeSignature
追加到函数名称以将其与复杂类型关联的字符串。 下划线之间必须有一个字符或多个字符。 例如, _xwcs_t_

优先
此元素是保留的,必须设置为零。

插槽
指定 WPP 预处理器传递给此复杂类型的 TraceMessage 函数的可变长度参数的最大数目。 此格式元素是可选的。 如果未指定此元素,则 WPP 使用默认值 1。

示例

若要定义复杂类型,请执行以下操作:

  1. 创建本地配置文件。 此文件应包含定义复杂类型的DEFINE_CPLX_TYPE宏。

  2. 指定 WPP 预处理器的本地配置文件。 打开项目属性。 在 “WPP 跟踪“文件选项”下,使用 “其他配置文件” 字段指定配置文件的名称 (-ini 参数) 。 请务必通过将“运行 WPP”设置为“”来启用 WPP 跟踪。 有关详细信息,请参阅 WPP 预处理器。

例如,可以创建一个本地配置文件 (Localwpp.ini) ,用于定义名为 .*ls 的复杂类型。 按以下方式定义复杂类型:

DEFINE_CPLX_TYPE(.*ls, WPP_LOGXWCS, const xwcs_t&, ItemPWString,"s", _xwcs_t_, 0, 2);

然后,当 WPP 看到类型 .*ls 时,例如:

printf("my string is %.*ls", value);

WPP 生成以下暂存函数 (其中 SF 表示“暂存函数”) :

WPP_SF__xwcs_t_(..., const xwcs_t& a1) {
    TraceMessage(..., WPP_LOGXWCS(a1) 0);
}

然后,WPP 生成一个 MOF 条目,例如在以下字符串中,其中 .*ls 类型名称替换为相应的 MOF 格式 %s

"my string is %s"
{
    Value, ItemPWString
}

它还为 类型生成结构,例如

struct xwcs_t {
      WCHAR*    _buf;
      short     _len;
      xwcs_t(short buf, short len):_buf(buf),_len(len){}
};

现在,添加一个宏,将数据类型合并为 xwstr_t 类型的字符串,如下所示:

#define WPP_LOGXWCS(x) WPP_LOGPAIR(2, &(x)._len) WPP_LOGPAIR((x)._len, (x)._buf)

其中 ,ItemPWString 是由 WPP 识别的计数 Unicode 字符串类型。 长度指定为 2 个字节。

当 ETW 解释WPP_LOGXWCS定义时,它会将 2 字节字符串放入解释第一个 WPP_LOGPAIR 宏的缓冲区中。 然后,当 ETW 解释第二个WPP_LOGPAIR宏时,ETW 会将字符串的所有字节复制到缓冲区中,

由于指定了独立于数据的长度,因此WPP_LOGXWCS使用 TraceMessage 的两个槽。 因此,数字 2 是第八个参数。

调用 WPP 预处理器时,请使用 “忽略感叹号 ”选项 (-noshrieks) 。 这有助于 WPP 识别名称未括在感叹号 (!) 的复杂类型,也称为“shrieks”。

有关 WPP 跟踪选项的完整列表以及如何从项目属性页设置它们的信息,请参阅 WPP 预处理器