2012-11-07 8 views
6

मैं एक पहले से लिखे कोड के माध्यम से जा रहा हूँ और मैंने पाया StringCbPrintf() समारोहस्ट्रिंग कैबप्रिंटफ क्या है और यह सामान्य स्प्रिंटफ से अलग कैसे है?

मैं msdn साइट पर इस तरह घोषणा पाया:

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

_in_ और _out_ यहाँ क्या है?

और जब हमारे पास पहले से sprintf() है तो इसकी आवश्यकता क्यों है?

+0

जोड़ा गया "विंडोज़" और "winapi" टैग, क्योंकि इस प्रश्न में एसएएल एनोटेशन शामिल हैं, जो विंडोज विशिष्ट हैं। –

+0

ध्यान दें कि '_in_' और' _out_' वैध SAL मान्य नहीं हैं (वे शुरुआती पूंजी पत्र के साथ '_In_' और' _Out_' हैं)। एक वैकल्पिक वैध एसएएल अग्रणी डबल अंडरस्कोर (और लोअरकेस प्रारंभिक अक्षर) के साथ है: '__in' और' __out'। –

उत्तर

8

_In_ और _Out_ (टिप्पणी: न तो _in_/_out _ के रूप में आप ने लिखा है, और न ही __In__/__Out__ डबल अंडरस्कोर, कुछ अन्य जवाब में लिखा के रूप में) के साथ तो साल एनोटेशन कहा जाता है। उनका उपयोग /analyze कंपाइलर विकल्प के साथ किया जा सकता है, और कच्चे सी बफर और पॉइंटर्स के साथ बफर ओवररन्स इत्यादि जैसी बग और समस्याओं की पहचान करने में मदद कर सकता है। MSDN documentation on SAL के अतिरिक्त, आप यह भी blog post पढ़ सकते हैं।

किसी विडंबना यह है कि (और को गलत तरीके से) ने लिखा है कि:

"दुनिया के बाकी हिस्सों में, आदानों स्थिरांक संकेत दिए गए हैं, लेकिन मुझे लगता है कि कि भी आसान था :)।"

इस तथ्य को याद नहीं है कि SAL उससे अधिक शक्तिशाली है। वास्तव में, एसएएल के साथ आप गंतव्य बफर का अधिकतम आकार भी निर्दिष्ट कर सकते हैं, यह दर्शाता है कि कौन से पैरामीटर में गंतव्य बफर आकार होता है; जैसे यदि आप <strsafe.h> हैडर खोलते हैं, तो आप पढ़ सकते हैं कि वास्तविक साल StringCbPrintfW (StringCbPrintf का यूनिकोड संस्करण) के लिए इस्तेमाल किया एनोटेशन ऐसा ही कुछ है:

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

नोट कैसे __out_bcount(cbDest) साल एनोटेशन pszDest पैरामीटर के लिए लागू निर्दिष्ट करता है यह है कि एक उत्पादन बफर (__out) है, जो आकार पैरामीटर cbDest द्वारा बाइट्स (_bcount) में व्यक्त किया जाता है के लिए सूचक है। जैसा कि आप देख सकते हैं, यह समृद्ध एनोटेशन (सरल "const" या "गैर const" से समृद्ध है)।

मेरी राय में, साल एक तरह से बेकार है अगर आप सी std::vector या std::string की तरह मजबूत कंटेनर कक्षाएं, जो अपने ही आकार, आदि पता लेकिन साल कच्चे संकेत के साथ सी-ish कोड में उपयोगी हो सकता है के साथ ++ कोड लिखने (जैसे कई Win32 एपीआई)।

अपने प्रश्न के दूसरे भाग के बारे में:

मुख्य कारण यह है कि sprintf एक असुरक्षित है कि "क्यों हम StringCbPrintf जरूरत है अगर हम पहले से ही sprintf है" और overruns- बफ़र प्रवण समारोह; इसके बजाय StringCbPrintf के साथ आपको गंतव्य बफर का अधिकतम आकार निर्दिष्ट करना होगा, और यह बफर ओवररन्स को रोकने में मदद कर सकता है (जो सुरक्षा दुश्मन हैं)।

2

The documentation समझाने के लिए है कि आप के लिए कोशिश करता है:

तुलना में कार्यों यह बदल देता है, StringCbPrintf उचित बफर अपने कोड में से निपटने के लिए अतिरिक्त संसाधन उपलब्ध कराता है। खराब बफर हैंडलिंग को कई सुरक्षा मुद्दों में शामिल किया गया है जिनमें बफर ओवररन्स शामिल हैं। StringCbPrintf हमेशा एक गैर-शून्य-लंबाई गंतव्य बफर को समाप्त करता है।

__In__ और __Out__ सज्जाकार माइक्रोसॉफ्ट एपीआई में किया जाता है: निरूपित करने के लिए कैसे एक सूचक तर्क प्रयोग किया जाता है है। दुनिया के बाकी हिस्सों में, इनपुट const पॉइंटर्स हैं लेकिन मुझे लगता है कि यह बहुत आसान था। :)

+0

नाइस .. इसका मतलब है '__in__' का मतलब आउटपुट बफर के लिए 'const' और' __out__' है। लेकिन इसकी आवश्यकता क्यों है? हम सही sprintf है? – Omkant

+0

+1 __in__ और __out__ के लिए वैसे भी, मैं एक प्रकार का बाध्यकारी param सोच रहा था जैसे हमारे पास डेटाबेस फ़ंक्शंस – Omkant

+0

में है नोट करें कि '__In__' और' __Out__' गलत हैं: मान्य SAL '__in/__ आउट' हैं (जैसा निर्दिष्ट है [यहां] (http://msdn.microsoft.com/en-us/library/ms235402(v=vs.80).aspx)) या '_In _/_ आउट_' (निर्दिष्ट [यहां] (http://msdn.microsoft। com/en-us/पुस्तकालय/ms235402 (v = vs.100) .aspx))। इसके अलावा, -1 क्योंकि एसएएल सरल 'const' शुद्धता से _richer_ है। –

2

के रूप में यह कहा जाता है here:,

  • sprintf, swprintf _stprintf
  • wsprintf
  • wnsprintf
  • _snprintf:

    StringCbPrintf निम्नलिखित कार्य के लिए एक स्थानापन्न है , _snwprintf, _sntprintf

तो यह न केवल sprintf को प्रतिस्थापित करता है, बल्कि wchar के साथ काम करने के लिए भी, उदाहरण के लिए। यह बफर ओवररन्स को रोकने के लिए अतिरिक्त बफर प्रोसेसिंग भी प्रस्तुत करता है (जैसा कि उसी एमएसडीएन आलेख में बताया गया है)। यह हमेशा गंतव्य बफर को शून्य-समाप्त करता है। _in_ और _out_ आपको यह दिखाने के लिए हैं कि कौन से पैरामीटर इनपुट वाले हैं, और जो आउटपुट हैं। सबसे अधिक संभावना #define डी कुछ भी नहीं है, और संकलन शुरू होने से पहले चले जाओ।

+0

अच्छा यह लाइन msdn में लिखा गया था लेकिन समस्या __in__ और __out__ के साथ थी .. वैसे भी +1 – Omkant

+0

@ ओमकांत, कई पुस्तकों में आप सी ++ पर पढ़ सकते हैं, लेखक वास्तव में इनपुट और आउटपुट फ़ंक्शन तर्कों को अलग करने की अनुशंसा करते हैं। एक समाधान ऐसे मैक्रोज़ का उपयोग कर रहा है, उदा। '# परिभाषित करें 'और' # परिभाषित करें '।वे स्पष्ट रूप से तर्क प्रकार दिखाते हैं, और संकलन शुरू होने से पहले चले जाते हैं। मैं आपको ऐसा करने के लिए प्रोत्साहित नहीं कर रहा हूं, यह केवल कुछ अतिरिक्त जानकारी है: पी – SingerOfTheFall

+0

धन्यवाद मुझे यह मिला – Omkant

संबंधित मुद्दे