2009-03-03 16 views
17

मैं सी डीएल से वीबीChar * से BSTR को कैसे परिवर्तित करें?

से char * कैसे पास कर सकता हूं यहां नमूना कोड है:

void Cfunc(char *buffer,int len) 
{ 
    BSTR buf_bstr = SysAllocString((BSTR)buffer); 
    VBptr.VBfunc(buf_bstr,len); 
} 

यह फ़ंक्शन काम नहीं कर रहा है, वास्तव में कुछ अन्य मान वास्तविक मूल्य की बजाय वीबी को भेजे जाते हैं ।

क्या कोई भी समाधान का सुझाव दे सकता है?

+0

क्या आप एक मूल स्ट्रिंग बनाम गलत मूल्य बनाम भेजा जा सकता है? –

+0

आपकी (मूल) समस्या चरित्र चौड़ाई प्रतीत होती है। एक बीस्ट्र हमेशा चौड़ा वर्ण होता है (COM सभी यूनिकोड है)। एक कलाकार स्वचालित रूप से वर्णों को विस्तृत नहीं करेगा, लेकिन बाइट्स को wchar_t * के रूप में समझें। – Richard

+0

इस छद्म कोड में मेमोरी रिसाव है। आप SysAllocString() को कॉल करते हैं, लेकिन स्ट्रिंग को डिलीकेट नहीं करते हैं, इसके बाद आपको इसकी आवश्यकता नहीं होती है। – sharptooth

उत्तर

18

उपयोग _bstr_t:

_bstr_t bstrt(buffer); 

यहाँ holy grail of string conversion articles

+0

_bstr_t एक वर्ग है। शुद्ध सी के लिए उपयोगी नहीं है, मुझे लगता है। – sharptooth

+0

हाँ आप सही हैं। धन्यवाद –

+0

ग्रेट लिंक, धन्यवाद! – Colen

2

मैं जवाब ajryan को कोई आपत्ति नहीं है, लेकिन यहाँ एक विकल्प है ...

SysAllocString एक लेने के लिए परिभाषित किया गया है ओलेचर * प्रकार का पैरामीटर। आप इसे एक char * दे रहे हैं। ये वही बात नहीं हैं। कुछ परिस्थितियां हैं जब वे एक ही चीज़ हो सकती हैं, लेकिन आप इस पर निर्भर नहीं हो सकते हैं। तो सबसे पहले आपको अपने char * को OLECHAR * में परिवर्तित करने की आवश्यकता है। ए 2 ओएलई नामक एक मैक्रो है जो आपके लिए यह कर सकता है, और उन मामलों में जहां char * और OLECHAR * एक ही चीज़ हैं, मैक्रो कुछ भी नहीं (मुझे लगता है) संकलित करता है।

ए 2 ओएलई और उसके दोस्तों के विवरण के लिए this page देखें।

ओह, और अपने चार * को एक बीस्ट्रेट में कास्टिंग करना वास्तव में इसे बिल्कुल नहीं बदलता है, यह न तो एक बीस्ट्र है और न ही ओलेचर * है।

+0

बीटीडब्ल्यू, एक WCHAR * को बीस्ट्रेट कास्टिंग करना भी एक बुरा विचार है यदि स्ट्रिंग को SysAllocString() परिवार कार्यों में से किसी एक के साथ आवंटित नहीं किया गया है। ऐसा करने से क्रैश हो सकता है यदि आप इस तरह के छद्म-बीएसटी को कॉल करते हैं तो उस पर SysStringLen() कॉल करता है। – sharptooth

21

कॉल मल्टीबाइट टॉइडहाइडर(), या तो SysAllocString() या SysAllocStringLen()।

SysFreeString() को कॉल करना न भूलें जब आपको अब BSTR की आवश्यकता नहीं है।

विस्तार में (SysAllocStringLen() संस्करण - यह छोटा है और तेजी से):

  1. कॉल MultiByteToWideChar() और 0 पांचवें और छठे पैरामीटर के रूप में गुजरती हैं। यह एएनएसआई स्ट्रिंग के बराबर यूनिकोड में वर्णों की संख्या वापस कर देगा। याद रखें, एएनएसआई स्ट्रिंग में जो भी अक्षर हो सकते हैं, न केवल ASCII, इसलिए एएनएसआई स्ट्रिंग लम्बाई दिए गए यूनिकोड वर्णों की मैन्युअल रूप से गणना करने के किसी भी प्रयास में कुछ मामलों में काम हो सकता है और दूसरों में काम नहीं कर सकता है।

  2. SysAllocStringLen() के साथ BSTR के लिए एक बफर आवंटित करें। पहले पैरामीटर के रूप में 0 को पास करें और यूनिकोड वर्णों की संख्या को दूसरे पैरामीटर के रूप में पास करें। अब आपके पास ठीक से आवंटित लेकिन अनियंत्रित BSTR है। यह पिछली शून्य के लिए पहले से ही है और यह पिछला शून्य सही ढंग से रखा गया है।

  3. कॉल मल्टीबाइट टोवाइडर() दूसरी बार कॉल करें और इस बार आवंटित BSTR पास करें। फ़ंक्शन स्ट्रिंग को यूनिकोड में परिवर्तित करेगा और परिणाम को BSTR में कॉपी करेगा। अब आपके पास एक आवंटित आवंटित BSTR है जिसमें यूनिकोड आपके एएनएसआई स्ट्रिंग के बराबर है।

  4. बीबीआर को वीबी में पास करें। का आनंद लें।

  5. BSTR को हटाने के लिए SysFreeString() को कॉल करें।

+0

फिर भी मेरा कोड काम नहीं कर रहा है, मैंने इस तरह संशोधित किया है। शून्य Cfunc (char * buffer, int len) { BSTR buf_bstr; उलझन सीएचएआरएक्टएक्टर्स; यदि (0 == मल्टीबाइट टॉवाइडर (0, 0, बफर, सीएचएआरएक्टएक्टर्स, buf_bstr, cCharacters)); VBptr.VBfunc (buf_bstr, लेन); } वीबी एक्स क्रैश हो गया है। –

+0

हाय शार्पतोथ .. मैं इस COM के लिए नया हूं :( –

+1

मैंने एक चरण-दर-चरण कैसे शामिल करने के लिए उत्तर संपादित किया है। – sharptooth

10

इस कोड मैं sharptooths जवाब

int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0); 
    BSTR bstr = SysAllocStringLen(0, wslen); 
    MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen); 
    // Use bstr here 
    SysFreeString(bstr); 

ध्यान दें कि अशक्त टर्मिनेटर में स्ट्रिंग परिणाम की लंबाई के लिए -1 का उपयोग कर परिणाम

1

में शामिल किए जाने का उपयोग कर लिखा है char * सरणी के बजाय, _tchar * array का प्रयास करें। क्योंकि Sysallocstring केवल 32 बिट अनुप्रयोग में यूनिकोड वर्ण लेता है।

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