2010-01-18 10 views
6

मुझे CString इंस्टेंस को उचित रूप से आवंटित BSTR में कनवर्ट करने और COM12 विधि में BSTR को पास करने की आवश्यकता है। कोड रखने के लिए जो एएनएसआई और यूनिकोड दोनों के लिए इंडेंटिक रूप से संकलित और काम करता है, मैं CString::AllocSysString() का उपयोग किसी भी प्रारूप CString को यूनिकोड BSTR में कनवर्ट करने के लिए करता हूं।सीएसटींग में बीएसआर को सर्वोत्तम रूप से परिवर्तित करने के लिए इसे COM विधि में "इन" पैरामीटर के रूप में कैसे पास किया जाए?

चूंकि कोई भी लौटा हुआ बीएसटी का मालिक नहीं है, इसलिए मुझे इसकी देखभाल करने की आवश्यकता है और कॉल के बाद इसे सबसे अपवाद-सुरक्षित तरीके से और यथासंभव कम कोड के साथ कॉल करने के बाद इसे रिलीज़ करने की आवश्यकता है।

वर्तमान में मैं जीवन भर के प्रबंधन के लिए ATL::CComBSTR का उपयोग करें:

ATL::CComBSTR converted; 
converted.Attach(sourceString.AllocSysString()); //simply attaches to BSTR, doesn't reallocate it 
interface->CallMethod(converted); 

क्या मैं यहाँ पसंद नहीं है कि मैं सिर्फ ATL::CComBSTR रूपांतरण परिणाम के लिए बाध्य के निर्माण के लिए दो अलग-अलग बयानों की जरूरत है।

क्या एक ही कार्य को पूरा करने का कोई बेहतर तरीका है?

उत्तर

14

CComBSTRchar* और wchar_t* दोनों के लिए निर्माताओं, जो आपकी ओर से SysAllocString() को कॉल करने अतिभारित किया है। तो आपके कोड स्निपेट में स्पष्ट आवंटन वास्तव में अनावश्यक है। , इसके अलावा

ATL::CComBSTR converted = sourceString; 
interface->CallMethod(converted); 

अगर आप अपने कोड में कहीं परिवर्तित BSTR उपयोग करने की आवश्यकता है, तो आप इन-जगह वस्तु निर्माण विधि कॉल में है, इसलिए की तरह प्रदर्शन कर सकते हैं: निम्नलिखित बस के रूप में अच्छी तरह से काम करेगा

interface->CallMethod(ATL::CComBSTR(sourceString)); 

ही _bstr_t वर्ग है, जो CComBSTR के बजाय इस्तेमाल किया जा सकता है अगर आप ATL पर निर्भरता नहीं करना चाहते करने के लिए लागू होता है।

+0

यह निश्चित रूप से काम करेगा, सिवाय इसके कि सीसीओएमबीस्ट्रक्टर कन्स्ट्रक्टर का उपयोग करने के साथ मुझे यह जांचना होगा कि बीएसटी आवंटन सफल रहा था (सीएसटींग :: ऑलोकिस स्ट्रिंग() चेक करता है और अपवाद फेंकता है) और _bstr_t के साथ मुझे देखभाल करना होगा _com_issue_error() फ़ंक्शन - या तो इसे ओवरराइड करें या उससे निकलने वाले _com_error को पकड़ें। – sharptooth

+0

क्यों बुलाया जाने वाला तरीका इसके तर्कों की वैधता की जांच करने के लिए ज़िम्मेदार नहीं है? यदि आवंटन विफल रहता है, तो 'CComBSTR :: m_str' शून्य हो जाएगा। तो या तो बुलाया गया तरीका शून्य के लिए जांच करेगा और 'E_INVALIDARG' वापस करेगा, या यह आपके द्वारा पहले से ही 'सीएसटींग :: AllocSysString()' के लिए 'कैच' नहीं होगा और आपके लिए अपवाद संभाल सकता है। यह स्पष्ट रूप से स्वयं को जांचने की तुलना में एक क्लीनर मुहावरे है, इमो। –

+1

@ फिल बूथ: बुलाया जाने वाला तरीका एक विशेष मामले के रूप में शून्य BSTR की व्याख्या कर सकता है। उदाहरण के लिए, अर्थ "फ़ाइल नाम निर्दिष्ट कर सकता है, यदि खाली स्ट्रिंग पास हो जाती है तो डिफ़ॉल्ट फ़ाइल नाम का उपयोग किया जाता है"। इसलिए बुलाए जाने की विधि को यह जानने का कोई मौका नहीं है कि कोई समस्या है। – sharptooth

2

विंडोज प्रोग्रामिंग के भ्रमित पहलुओं में से एक सी भाषा शैली तारों से/से विज़ुअल बेसिक स्टाइल स्ट्रिंग्स के रूपांतरण का प्रबंधन कर रहा है। ऐसा नहीं है कि यह इतना मुश्किल है, विवरणों को याद रखना मुश्किल है। यह आमतौर पर अक्सर नहीं किया जाता है, और एमएसडीएन दस्तावेज इतना विशाल है कि आपके प्रश्नों के उत्तर ढूंढना मुश्किल है। लेकिन, सबसे बुरा हिस्सा यह है कि आप कुछ टाइपकास्ट निष्पादित कर सकते हैं जो ठीक से संकलित करता है, लेकिन जिस तरह से आप उम्मीद करते हैं वह काम नहीं करता है। इसका परिणाम कोड में होता है जो काम नहीं करता है, और बग को ट्रैक करना मुश्किल होता है। कुछ अनुभव के बाद, आप यह सुनिश्चित करना सीखते हैं कि आपकी स्ट्रिंग रूपांतरण आप जो कर रहे हैं वह कर रहे हैं।

सी तार एक नल चरित्र द्वारा समाप्त वर्णों के सरणी हैं। दृश्य मूलभूत तार अलग-अलग होते हैं कि स्ट्रिंग की लंबाई स्ट्रिंग में वर्णों से पहले होती है। तो, एक वीबी स्ट्रिंग अपनी लंबाई जानता है। इसके अलावा, सभी वीबी तार यूनिकोड (16 बिट प्रति चरित्र) हैं। स्ट्रिंग प्रकार

BSTR/सी स्ट्रिंग रूपांतरण के लिए आवश्यक हैं, तो:

You are doing COM programming in C/C++ 
You are writing multiple language applications, such as C++ DLL's accessed by Visual Basic applications. 
1

_bstr_t कंस्ट्रक्टर्स में से एक तो आप बस मौजूदा BSTR इतना करने के लिए संलग्न करने के लिए आप अपवाद हो सकता है कि आप CString::AllocSysString से चाहते हैं जब BSTR आवंटन की अनुमति देता है विफल रहता है।

// _bstr_t simply attaches to BSTR, doesn't reallocate it 
interface->CallMethod(_bstr_t(sourceString.AllocSysString(), false)); 

_bstr_t constructor documentation का कहना है:

_bstr_t(
    BSTR bstr, 
    bool fCopy 
); 

fCopy
झूठे हैं, तो bstr तर्क SysAllocString को फोन करके एक प्रतिलिपि बनाने के बिना नई वस्तु से जुड़ी है।

दूसरी ओर, CComBSTR constructor इसी हस्ताक्षर है प्रतीत नहीं होता है; हालांकि इसका उपयोग BSTR आवंटन विफलता अपवाद की वास्तव में आवश्यक नहीं है, जैसा कि Phil Booth द्वारा his answer में उल्लिखित है।

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

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