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

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函数需要此格式的变量参数列表中的每个条目。

若要正确设置参数的格式,必须在 helper 宏的定义中使用 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 函数传递的可变长度参数的最大数目。 此 format 元素是可选的。 如果未指定此元素,则 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 然后在 ETW 解释第二个 WPP_LOGPAIR 宏时,将该字符串的所有字节复制到缓冲区中。

由于你指定了与数据分隔的长度,因此 WPP_LOGXWCS 会使用 TraceMessage的两个槽。 因此,数字 2 是第8个参数。

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

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