2010-12-03 16 views
6

क्या ऐसा करने का सही तरीका क्या है:_bstr_t का उपयोग करते हुए समारोह में के प्रकार BSTR * पैरामीटर पारित करने के लिए

_bstr_t description; 
errorInfo->GetDescription(&description.GetBSTR()); 

या:

_bstr_t description; 
errorInfo->GetDescription(description.GetAddress()); 

कहाँ IError:GetDescription परिभाषित किया गया है के रूप में:

HRESULT GetDescription (BSTR *pbstrDescription); 

मुझे पता है कि मैं आसानी से ऐसा कर सकता हूं:

BSTR description= SysAllocString (L"Whateva")); 
errorInfo->GetDescription (&description); 
SysFreeString (description); 

धन्यवाद

उत्तर

8

BSTR संदर्भ में गिना जाता है, मैं गंभीरता से संदेह काम करेंगे कि आप GetAddress का उपयोग सही है, तो()। अफसोस की बात है कि स्रोत कोड डबल-चेक करने के लिए उपलब्ध नहीं है। मैं हमेशा इस तरह यह किया है:

BSTR temp = 0; 
HRESULT hr = p->GetDescription(&temp); 
if (SUCCEEDED(hr)) { 
    _bstr_t wrap(temp, FALSE); 
    // etc.. 
} 
+0

+1, _bstr_t के BSTR की बात को अन्य मामलों द्वारा साझा किया जा रहा है, मुझे कुछ भी छोड़ दिया जो सीधे इसे असाइन कर सकता है। –

+1

क्या आप असाइनमेंट ऑपरेटर के बजाय 'अटैच() 'का उपयोग नहीं करना चाहिए? –

+0

जैसा कि दिखाया गया है, 'GetDescription' फ़ंक्शन 'SysAllocString' के साथ' temp' को स्मृति आवंटित करता है, और वह स्मृति कभी मुक्त नहीं होती है। या तो, आपको 'SysFreeString (temp)' को कॉल करना होगा, या यह सुनिश्चित करना होगा कि 'लपेटें' उस स्मृति से जुड़ती है और इसे मुक्त करती है। – abelenky

5

हंस का जवाब @ का पालन करने के लिए - _bstr_t के निर्माण के लिए उपयुक्त तरीका है कि क्या GetDescription रिटर्न आप एक BSTR आप के स्वामी है, या एक पर निर्भर करता है कि स्मृति को संदर्भित आप डॉन मुक्त नहीं है।

यहां लक्ष्य प्रतियों की संख्या को कम करने के लिए है, लेकिन लौटाए गए डेटा पर SysFreeString पर किसी भी मैन्युअल कॉल से बचें। के रूप में इस स्पष्ट करने के लिए दिखाया गया है मैं कोड को संशोधित करेगा:

BSTR temp = 0; 
HRESULT hr = p->GetDescription(&temp); 
if (SUCCEEDED(hr)) { 
    _bstr_t wrap(temp, false); // do not copy returned BSTR, which 
            // will be freed when wrap goes out of scope. 
            // Use true if you want a copy. 
    // etc.. 
} 
2

एक देर से जवाब यह है कि दृश्य स्टूडियो के पिछले (या बाद में) संस्करणों पर लागू नहीं हो सकता है; हालांकि, वीएस 12.0 में _bstr_t कार्यान्वयन इनलाइन है, और स्पष्ट रूप से एक आंतरिक Data_t उदाहरण m_RefCount के साथको कुंवारी _bstr_t पर कॉल करते समय बनाया गया है। तो अपने पहले उदाहरण में _bstr_t जीवन चक्र ठीक हो जाएगा दिखता है:

_bstr_t description; 
errorInfo->GetDescription(&description.GetBSTR()); 

लेकिन अगर _bstr_t गंदा है, मौजूदा आंतरिक m_wstr सूचक, ओवरराइट किया जाएगा पिछले स्मृति यह संदर्भित लीक।

निम्नलिखित operator& का उपयोग करके, एक गंदे _bstr_t का उपयोग किया जा सकता है क्योंकि यह पहली बार Assign(nullptr) के माध्यम से साफ़ किया गया है। अधिभार GetBSTR() के बजाय पता ऑपरेटर का उपयोग करने की सुविधा भी प्रदान करता है;

BSTR *operator&(_bstr_t &b) { 
    b.Assign(nullptr); 
    return &b.GetBSTR(); 
} 

तो, अपना पहला उदाहरण के बजाय ऐसा दिखाई दे सकता है:

_bstr_t description(L"naughty"); 
errorInfo->GetDescription(&description); 

यह मूल्यांकन वी.एस. 12.0 से comutil.h पर आधारित था।

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