什么是StringCbprintf,它与一般sprintf有何不同?
What is StringCbprintf and how's this different than general sprintf?
我正在浏览以前编写的代码,我发现了StringCbPrintf()
函数
我在网站上找到了这样的声明msdn
:
HRESULT StringCbPrintf(
_Out_ LPTSTR pszDest,
_In_ size_t cbDest,
_In_ LPCTSTR pszFormat,
_In_ ...
);
这里的_in_
和_out_
是什么?
当我们已经有sprintf()
时,为什么需要它?
_In_
和_Out_
(注意:既不是你写的_in_/_out
_,也不是其他答案中写的带有双下划线的__In__/__Out__
)是所谓的SAL注释。它们可以与/analyze
编译器选项一起使用,并且可以帮助识别错误和问题,如原始 C 缓冲区和指针的缓冲区溢出等。除了有关 SAL 的 MSDN 文档外,您还可以阅读此博客文章。
具有讽刺意味的是(并且错误地)有人写道:
"在世界其他地方,输入是常量指针,但我想 太简单了。:)">
忽略了SAL比这更强大的事实。实际上,使用 SAL,您还可以指定目标缓冲区的最大大小,指示哪个参数包含目标缓冲区大小;例如,如果您打开<strsafe.h>
标头,您可以读到用于StringCbPrintfW
的实际 SAL 注释(StringCbPrintf
的 Unicode 版本)是这样的:
STRSAFEAPI
StringCbPrintfW(
__out_bcount(cbDest) STRSAFE_LPWSTR pszDest,
__in size_t cbDest,
__in __format_string STRSAFE_LPCWSTR pszFormat,
...)
{
....
请注意应用于pszDest
参数的__out_bcount(cbDest)
SAL注释如何指定这是指向输出缓冲区(__out
)的指针,其大小由参数cbDest
以字节(_bcount
)表示。如您所见,这是一个丰富的注释(比简单的"const
"或"nonconst
"更丰富)。
在我看来,如果您使用强大的容器类(如std::vector
或std::string
编写C++代码,则 SAL 毫无用处,它们知道自己的大小等。但是SAL在带有原始指针(如几个Win32 API)的C-ish代码中很有用。
关于您问题的第二部分:
"如果我们已经有了
sprintf
,为什么我们需要StringCbPrintf
">
主要原因是sprintf
是一个不安全且容易发生缓冲区溢出的函数;相反,对于StringCbPrintf
,您必须指定目标缓冲区的最大大小,这有助于防止缓冲区溢出(这是安全敌人)。
文档试图为您解释这一点:
与它所取代的函数相比,StringCbPrintf 为 代码中适当的缓冲区处理。缓冲区处理不当与许多涉及缓冲区溢出的安全问题有关。StringCbPrintf 始终以 null 结尾的非零长度目标缓冲区。
__In__
和__Out__
装饰器Microsoft API:s 中用于表示如何使用指针参数。在世界其他地方,输入是指针const
,但我想这太简单了。:)
正如这里所说:
StringCbPrintf 是以下函数的替代品:
- sprintf, swprintf, _stprintf
- wsprintf
- wnsprintf
- _snprintf、_snwprintf_sntprintf
因此,它不仅取代了sprintf
,而且还取代了那些与wchar
一起工作的,例如。它还引入了额外的缓冲区处理以防止缓冲区溢出(如同一 msdn 文章中所述)。它还始终以 null 终止目标缓冲区。_in_
和_out_
可以向您展示哪些参数是输入参数,哪些参数是输出参数。这些很可能#define
为无,并在编译开始之前消失。
- Python中的for循环与C++有何不同
- 在C++中释放内存期间,迭代器与指针有何不同
- -fvisibility-inline-hidden 与 gcc 中的 -fvisibility=hidden 有何不同
- 收益率和回报有何不同?
- 覆盖私有功能,它与受保护功能有何不同?
- 无论代码长度如何,以下代码的内存要求有何不同?
- stl::unordered_map 和 stl::vector 的销毁有何不同
- C++ 友元函数在内存位置上有何不同?
- C 是否具有接口类概念,如果它在那里,那么它与Java接口类别有何不同
- std::u8string与std::string有何不同?
- 两种类型转换有何不同?
- 这个语句到底是什么意思 stack<int, list<int> > 它与 stack 有何不同<int>?
- 英特尔®事务同步扩展新指令 (TSX-NI) 与英特尔 TSX 有何不同?
- 指向成员函数的指针与指向数据成员的指针有何不同
- 字符 * 和字符串在C++中有何不同?(在描述中编写代码)
- 在C++中,Mixin与面向策略的设计有何不同
- "cin>>"与"cin.get"有何不同?还是不是?
- C++11: boost::make_tuple 与 std::make_tuple 有何不同?
- 双重列表复制构造函数:与单一列表复制构造函数有何不同
- 什么是StringCbprintf,它与一般sprintf有何不同?