我正在阅读以前编写的代码,并找到了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 Annotations.它们可以与/ analyze编译器选项一起使用,并且可以帮助识别缓冲区溢出等错误和问题,以及原始C缓冲区和指针.除了
MSDN documentation on SAL,您还可以阅读此
blog post.
有人讽刺(并且错误地)写道:
“In the rest of the world,inputs are const pointers but I guess that
was too simple. :)”
错过SAL比这更强大的事实.事实上,使用SAL,您还可以指定目标缓冲区的最大大小,指示哪个参数包含目标缓冲区大小;例如如果你打开< strsafe.h>标题,您可以读到用于StringCbPrintfW(StringCbPrintf的Unicode版本)的实际SAL注释是这样的:
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”或“非const”更丰富).
在我看来,如果你用强大的容器类(如std :: vector或std :: string)编写C代码,它们有点无用,它们知道它们自己的大小等等.但SAL在带有原始指针的C-ish代码中很有用. (像几个Win32 API).
关于你问题的第二部分:
“Why we need
StringCbPrintf
if we already havesprintf
“
主要原因是sprintf是一种不安全且容易出现缓冲溢出的功能;而不是使用StringCbPrintf,您必须指定目标缓冲区的最大大小,这有助于防止缓冲区溢出(这是安全的敌人).