标头批注
[本主题介绍通过 Windows 7 的 Windows 标头中支持的批注。 如果要针对 Windows 8 进行开发,则应使用 SAL 批注中所述的注释。]
标头注释描述函数如何使用其参数和返回值。 这些批注已添加到许多 Windows 头文件,以帮助确保正确调用 Windows API。 如果启用从 Visual Studio 2005 开始可用的代码分析,如果不是根据注释中所述的使用调用这些函数,编译器将生成级别 6000 警告。 还可以在自己的代码中添加这些批注,以确保正确调用它。 若要在 Visual Studio 中启用代码分析,请参阅 Visual Studio 版本的文档。
这些批注在 Specstrings.h 中定义。 它们基于标准批注语言(SAL)的基元构建,并使用 _declspec("SAL_*")
实现。
有两类批注:缓冲区批注和高级批注。
缓冲区批注
缓冲区注释描述函数如何使用其指针,并可用于检测缓冲区溢出。 每个参数可以使用零个或一个缓冲区批注。 缓冲区批注是用前导下划线和以下部分中介绍的组件构造的。
缓冲区大小 | 描述 |
---|---|
(大小) |
指定缓冲区的总大小。 与_bcount和_ecount配合使用;请勿与_part一起使用。 此值是可访问的空间;它可能小于分配的空间。 |
(大小,长度) |
指定缓冲区的总大小和初始化长度。 与_bcount_part和_ecount_part一起使用。 总大小可能小于分配的空间。 |
缓冲区大小单位 | 描述 |
---|---|
_bcount |
缓冲区大小以字节为单位。 |
_ecount |
缓冲区大小在元素中。 |
方向 | 描述 |
---|---|
_in |
该函数从缓冲区读取。 调用方提供缓冲区并初始化它。 |
_inout |
该函数同时读取和写入缓冲区。 调用方提供缓冲区并初始化它。 如果与_deref一起使用,则缓冲区可能会被函数重新分配。 |
_out |
函数写入缓冲区。 如果对返回值或_deref使用,则函数提供缓冲区并初始化它。 否则,调用方提供缓冲区,函数初始化它。 |
间接 | 描述 |
---|---|
_deref |
取消引用参数以获取缓冲区指针。 此参数可能不 NULL。 |
_deref_opt |
取消引用参数以获取缓冲区指针。 此参数可以 NULL。 |
初始化 | 描述 |
---|---|
_full |
该函数初始化整个缓冲区。 仅用于输出缓冲区。 |
_part |
该函数初始化缓冲区的一部分,并显式指示了多少。 仅用于输出缓冲区。 |
必需或可选缓冲区 | 描述 |
---|---|
_opt |
此参数可以 NULL。 |
以下示例显示了 GetModuleFileName 函数的批注。 hModule 参数是可选的输入参数。 lpFilename 参数是输出参数;其大小(以字符为单位)由 nSize 参数指定,其长度包括 null-terminating 字符。 nSize 参数是输入参数。
DWORD
WINAPI
GetModuleFileName(
__in_opt HMODULE hModule,
__out_ecount_part(nSize, return + 1) LPTSTR lpFilename,
__in DWORD nSize
);
以下是 Specstrings.h 中定义的批注。 使用上述表中的信息来解释其含义。
__bcount(大小)
__bcount_opt(大小)
__deref_bcount(大小)
__deref_bcount_opt(大小)
__deref_ecount(大小)
__deref_ecount_opt(大小)
__deref_in
__deref_in_bcount(大小)
__deref_in_bcount_opt(大小)
__deref_in_ecount(大小)
__deref_in_ecount_opt(大小)
__deref_in_opt
__deref_inout
__deref_inout_bcount(大小)
__deref_inout_bcount_full(大小)
__deref_inout_bcount_full_opt(大小)
__deref_inout_bcount_opt(大小)
__deref_inout_bcount_part(大小,长度)
__deref_inout_bcount_part_opt(大小,长度)
__deref_inout_ecount(大小)
__deref_inout_ecount_full(大小)
__deref_inout_ecount_full_opt(大小)
__deref_inout_ecount_opt(大小)
__deref_inout_ecount_part(大小,长度)
__deref_inout_ecount_part_opt(大小,长度)
__deref_inout_opt
__deref_opt_bcount(大小)
__deref_opt_bcount_opt(大小)
__deref_opt_ecount(大小)
__deref_opt_ecount_opt(大小)
__deref_opt_in
__deref_opt_in_bcount(大小)
__deref_opt_in_bcount_opt(大小)
__deref_opt_in_ecount(大小)
__deref_opt_in_ecount_opt(大小)
__deref_opt_in_opt
__deref_opt_inout
__deref_opt_inout_bcount(大小)
__deref_opt_inout_bcount_full(大小)
__deref_opt_inout_bcount_full_opt(大小)
__deref_opt_inout_bcount_opt(大小)
__deref_opt_inout_bcount_part(大小,长度)
__deref_opt_inout_bcount_part_opt(大小,长度)
__deref_opt_inout_ecount(大小)
__deref_opt_inout_ecount_full(大小)
__deref_opt_inout_ecount_full_opt(大小)
__deref_opt_inout_ecount_opt(大小)
__deref_opt_inout_ecount_part(大小,长度)
__deref_opt_inout_ecount_part_opt(大小,长度)
__deref_opt_inout_opt
__deref_opt_out
__deref_opt_out_bcount(大小)
__deref_opt_out_bcount_full(大小)
__deref_opt_out_bcount_full_opt(大小)
__deref_opt_out_bcount_opt(大小)
__deref_opt_out_bcount_part(大小,长度)
__deref_opt_out_bcount_part_opt(大小,长度)
__deref_opt_out_ecount(大小)
__deref_opt_out_ecount_full(大小)
__deref_opt_out_ecount_full_opt(大小)
__deref_opt_out_ecount_opt(大小)
__deref_opt_out_ecount_part(大小,长度)
__deref_opt_out_ecount_part_opt(大小,长度)
__deref_opt_out_opt
__deref_out
__deref_out_bcount(大小)
__deref_out_bcount_full(大小)
__deref_out_bcount_full_opt(大小)
__deref_out_bcount_opt(大小)
__deref_out_bcount_part(大小,长度)
__deref_out_bcount_part_opt(大小,长度)
__deref_out_ecount(大小)
__deref_out_ecount_full(大小)
__deref_out_ecount_full_opt(大小)
__deref_out_ecount_opt(大小)
__deref_out_ecount_part(大小,长度)
__deref_out_ecount_part_opt(大小,长度)
__deref_out_opt
__ecount(大小)
__ecount_opt(大小)
__在
__in_bcount(大小)
__in_bcount_opt(大小)
__in_ecount(大小)
__in_ecount_opt(大小)
__in_opt
__inout
__inout_bcount(大小)
__inout_bcount_full(大小)
__inout_bcount_full_opt(大小)
__inout_bcount_opt(大小)
__inout_bcount_part(大小,长度)
__inout_bcount_part_opt(大小,长度)
__inout_ecount(大小)
__inout_ecount_full(大小)
__inout_ecount_full_opt(大小)
__inout_ecount_opt(大小)
__inout_ecount_part(大小,长度)
__inout_ecount_part_opt(大小,长度)
__inout_opt
__外
__out_bcount(大小)
__out_bcount_full(大小)
__out_bcount_full_opt(大小)
__out_bcount_opt(大小)
__out_bcount_part(大小,长度)
__out_bcount_part_opt(大小,长度)
__out_ecount(大小)
__out_ecount_full(大小)
__out_ecount_full_opt(大小)
__out_ecount_opt(大小)
__out_ecount_part(大小,长度)
__out_ecount_part_opt(大小,长度)
__out_opt
高级批注
高级批注提供有关参数或返回值的其他信息。 每个参数或返回值都可以使用零个或一个高级批注。
注解 | 描述 |
---|---|
__blocksOn(资源) |
函数在指定资源上块。 |
__callback |
该函数可用作函数指针。 |
__checkReturn |
调用方必须检查返回值。 |
__format_string |
参数是一个字符串,其中包含 printf 样式 % 标记。 |
__in_awcount(expr,大小) |
如果表达式在退出时为 true,则输入缓冲区的大小以字节为单位指定。 如果表达式为 false,则元素中指定大小。 |
__nullnullterminated |
最多可访问缓冲区,包括两个 null 字符或指针的第一个序列。 |
__nullterminated |
最多可访问缓冲区,包括第一个 null 字符或指针。 |
__out_awcount(expr,大小) |
如果表达式在退出时为 true,则输出缓冲区的大小以字节为单位指定。 如果表达式为 false,则元素中指定大小。 |
__override |
指定虚拟方法的 C#样式重写行为。 |
__reserved |
参数保留供将来使用,必须为零或 NULL。 |
__success(expr) |
如果表达式在退出时为 true,则调用方可以依赖于其他批注指定的所有保证。 如果表达式为 false,则调用方不能依赖保证。 此批注会自动添加到返回 HRESULT 值的函数中。 |
__typefix(ctype) |
将参数视为指定类型,而不是其声明的类型。 |
以下示例显示了 DeleteTimerQueueTimer、FreeEnvironmentStrings以及 UnhandledExceptionFilter 函数的缓冲区和高级批注。
__checkReturn
BOOL
WINAPI
DeleteTimerQueueTimer(
__in_opt HANDLE TimerQueue,
__in HANDLE Timer,
__in_opt HANDLE CompletionEvent
);
BOOL
WINAPI
FreeEnvironmentStrings(
__in __nullnullterminated LPTCH
);
__callback
LONG
WINAPI
UnhandledExceptionFilter(
__in struct _EXCEPTION_POINTERS *ExceptionInfo
);