Что такое StringCbprintf и чем он отличается от общего sprintf?

Я иду через ранее написанный код, и я нашел StringCbPrintf() функция

Я нашел объявление на msdn сайт, как это:

HRESULT StringCbPrintf(
_Out_  LPTSTR pszDest,
_In_   size_t cbDest,
_In_   LPCTSTR pszFormat,
_In_    ...
);

Что такое _in_ а также _out_ Вот ?

И зачем это нужно, когда у нас уже есть sprintf() ?

6

Решение

_In_ а также _Out_ (нота: ни _in_/_out_ как вы написали, ни __In__/__Out__ с двойным подчеркиванием, как написано в другом ответе), так называемые SAL Аннотации. Их можно использовать с /analyze опция компилятора, и может помочь выявить ошибки и проблемы, такие как переполнение буфера и т. д. с необработанными C-буферами и указателями. В дополнение к Документация MSDN по SAL, Вы также можете прочитать это Сообщение блога.

Кто-то по иронии судьбы (и превратно) написал что:

«В остальном мире входные данные являются постоянными указателями, но я думаю, что
было слишком просто. :)»

упустив тот факт, что SAL является более могущественный чем это. Фактически, с помощью SAL вы также можете указать максимальный размер буфера назначения, указывая, какой параметр содержит размер буфера назначения; например если вы откроете <strsafe.h> заголовок, вы можете прочитать, что фактические аннотации SAL используются для StringCbPrintfW (Unicode-версия StringCbPrintf) как то так

STRSAFEAPI
StringCbPrintfW(
__out_bcount(cbDest) STRSAFE_LPWSTR pszDest,
__in size_t cbDest,
__in __format_string STRSAFE_LPCWSTR pszFormat,
...)
{
....

Обратите внимание, как __out_bcount(cbDest) SAL аннотация применяется к pszDest параметр указывает, что это указатель на выход буфер (__out), который размер выражается в байтах (_bcount) по параметру cbDest, Как видите, это богатые аннотация (богаче простого «const«или» не const«).

На мой взгляд, SAL отчасти бесполезен, если вы пишете код на C ++ с такими надежными классами контейнеров, как std::vector или же std::string, которые знают свой собственный размер и т. д. Но SAL может быть полезен в коде C-ish с необработанными указателями (например, несколько Win32 API).

О второй части вашего вопроса:

«Зачем нам нужно StringCbPrintf если у нас уже есть sprintf«

главная причина в том, что sprintf является небезопасный и функция, склонная к переполнению буфера; вместо StringCbPrintf Вы должны указать максимальный размер буфера назначения, и это может помочь предотвратить переполнение буфера (которые являются врагами безопасности).

8

Другие решения

Документация пытается объяснить, что для вас:

По сравнению с функциями, которые он заменяет, StringCbPrintf обеспечивает дополнительную обработку для
правильная обработка буфера в вашем коде. Плохая обработка буфера связана со многими проблемами безопасности, которые включают переполнение буфера. StringCbPrintf всегда завершается нулем с целевым буфером ненулевой длины.

__In__ а также __Out__ декораторы используются в Microsoft API: s для обозначения использования аргумента указателя. В остальном мире вклад const указатели, но я думаю, это было слишком просто. 🙂

2

Как говорится Вот:

StringCbPrintf является заменой для следующих функций:

  • sprintf, swprintf, _stprintf
  • wsprintf
  • wnsprintf
  • _snprintf, _snwprintf, _sntprintf

Так что это не только заменить sprintfно и те, с которыми можно работать wchar, например. Он также вводит дополнительную обработку буфера для предотвращения переполнения буфера (как указано в той же статье msdn). Это также всегда null-завершает целевой буфер. _in_ а также _out_ там, чтобы показать вам, какие параметры являются входными, а какие выходными. Это наиболее вероятно #defined как ничто, и уходи до начала компиляции.

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector