2012-11-07 98 views
6

我打算通過先前編寫的代碼,我發現StringCbPrintf()功能什麼是StringCbprintf,這與一般的sprintf有何不同?

我發現msdn這樣的網站聲明:

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

什麼是_in__out_這裏?

爲什麼需要我們已經有sprintf()

+0

添加了「windows」和「winapi」標記,因爲此問題涉及SAL註釋,這是Windows特定的。 –

+0

請注意'_in_'和'_out_'不是有效的SAL(它們是'_In_'和'_Out_',以大寫字母開頭)。另一個有效的SAL帶有前導雙下劃線(和小寫字母首字母):'__in'和'__out'。 –

回答

8

_In__Out_:既不_in_/_out _爲你寫,也不__In__/__Out__雙下劃線,寫在一些其他的答案)是所謂的SAL註釋。它們可以與/analyze編譯器選項一起使用,並且可以使用原始C緩衝區和指針幫助識別錯誤和問題,如緩衝區溢出等。除了MSDN documentation on SAL,您還可以閱讀這個blog post

有人諷刺意味的是(和錯誤)寫道:

「在世界其他地方,輸入是const的指針,但我想這 太簡單了:)。」

錯過了SAL是比這更強大的事實。實際上,對於SAL,您還可以指定目標緩衝區的最大大小,指示哪個參數包含目標緩衝區大小;例如如果你打開<strsafe.h>頭,你可以讀取用於StringCbPrintfW(Unicode版本的StringCbPrintf)實際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」)。

在我看來,SAL是一種無用的,如果你寫C++代碼具有強大的容器類,如std::vectorstd::string,哪知道自己的大小等,但SAL可以在C-ISH代碼與原始指針有用(如幾個Win32 API)。

關於你問題的第二部分:

「我們爲什麼需要StringCbPrintf如果我們已經有sprintf

的主要原因是sprintf不安全和緩衝overruns-俯臥撐功能;而不是StringCbPrintf您必須指定目標緩衝區的最大大小,這可以幫助防止緩衝區溢出(這是安全的敵人)。

2

The documentation試圖解釋給你:

相對於它取代的功能,StringCbPrintf代碼中的 適當的緩衝處理提供了額外的處理。緩衝區處理不佳涉及許多涉及緩衝區溢出的安全問題。 StringCbPrintf總是空終止非零長度的目標緩衝區。

__In____Out__裝飾器在Microsoft API中用於表示如何使用指針參數。在世界其他地方,輸入是const指針,但我想這太簡單了。 :)

+0

不錯..這意味着'__in__'表示'const'和'__out__'用於輸出緩衝區。但爲什麼需要?我們有sprintf嗎? – Omkant

+0

+1反正__in__和__out__,我想是一種結合PARAM的就像我們在數據庫功能有 – Omkant

+0

注意'__In__'和'__Out__'是錯誤的:有效的SAL的是'__in/__ out'(如指定[這裏] (http://msdn.microsoft.com/en-us/library/ms235402(v=vs.80).aspx))或'_In _/_ Out_'(按照[此處指定](http://msdn.microsoft.com/zh-cn/) COM/EN-US /庫/ ms235402(v = VS.100)的.aspx))。此外,-1因爲SAL比簡單的'const'正確性更重要。 –

2

據傳here

StringCbPrintf是用於以下功能的替換:

  • sprintf的,標準的swprintf,_stprintf
  • wsprintf
  • wnsprintf
  • _snprintf ,_snwprintf,_sntprintf

因此,它不僅取代sprintf,還包括那些與wchar一起工作的例子。它還引入了額外的緩衝區處理來防止緩衝區溢出(如同一篇msdn文章中所述)。它也總是空終止目標緩衝區。 _in__out_是告訴你哪些參數是輸入的,哪些是輸出的。這些最有可能是#defined,並且在編譯開始之前就離開了。

+0

好這條線被寫在MSDN,但問題是與__in__和__out__ ..反正+1 – Omkant

+0

@Omkant,在很多書你可能會在C++閱讀,作者竟然建議區分輸入和輸出功能參數。一種解決方案是使用這樣的宏,例如'#define IN'和'#define OUT'。他們清楚地顯示參數類型,並在編譯開始之前離開。我不鼓勵你這樣做,這只是一些額外的信息:P – SingerOfTheFall

+0

謝謝,我知道了 – Omkant

相關問題