标头批注
[本主题介绍 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。 |
初始化 | 说明 |
---|---|
_全 |
函数初始化整个缓冲区。 仅与输出缓冲区一起使用。 |
_部分 |
函数初始化部分缓冲区,并显式指示缓冲区的量。 仅与输出缓冲区一起使用。 |
必需或可选缓冲区 | 说明 |
---|---|
_选择 |
此参数可以为 NULL。 |
以下示例演示 GetModuleFileName 函数的注释。 hModule 参数是可选的输入参数 。 lpFilename 参数是输出参数;其大小(以字符为单位)由 nSize 参数指定,其长度包括 null 终止字符。 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
__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
__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
高级批注
高级注释提供有关参数或返回值的其他信息。 每个参数或返回值都可以使用零个或一个高级注释。
Annotation | 说明 |
---|---|
__blocksOn (资源) |
函数对指定资源进行阻止。 |
__回调 |
函数可用作函数指针。 |
__checkReturn |
调用方必须检查返回值。 |
__format_string |
参数是包含 printf 样式百分比标记的字符串。 |
__in_awcount (expr,size) |
如果表达式在退出时为 true,则输入缓冲区的大小以字节为单位指定。 如果表达式为 false,则会在 元素中指定大小。 |
__nullnullterminated |
可以最多访问缓冲区,包括两个 null 字符或指针的第一个序列。 |
__nullterminated |
缓冲区可以最多访问,包括第一个 null 字符或指针。 |
__out_awcount (expr,size) |
如果表达式在退出时为 true,则输出缓冲区的大小以字节为单位指定。 如果表达式为 false,则会在 元素中指定大小。 |
__覆盖 |
指定虚拟方法的 C#样式替代行为。 |
__保留 |
参数保留供将来使用,必须为零或 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
);