2008-11-17 16 views
6

मैं एटीएल में लिखा गया एक COM ऑब्जेक्ट हूं जिसे सी ++ एप्लिकेशन से उपयोग किया जाता है, और मैं दोनों के बीच BYTEs की एक सरणी पास करना चाहता हूं। COM/IDL का मेरा अनुभव अब तक सरल प्रकारों (बीएसटी, लांग, इत्यादि) पास करने तक ही सीमित है।COM का उपयोग कर एक सरणी पास कर रहे हैं?

क्या COM ऑब्जेक्ट कॉलर को सरणी पास करने का अपेक्षाकृत आसान तरीका है? उदाहरण के लिए, मैं अस्थायी फ़ाइलों के साथ गड़बड़ करने की बजाय कच्ची छवि (टीआईएफएफ) पास करना चाहता हूं।

+10

COM ऑब्जेक्ट होना कितना मजेदार होना चाहिए। :-) – Danra

उत्तर

11

COM ऑब्जेक्ट में एक सफेरेरे संस्करण को पारित करने का प्रयास करें। कुछ इस तरह एक SAFEARRAY संस्करण के अंदर एक बाइट सरणी डाल करने के लिए ....

bool ArrayToVariant(CArray<BYTE, BYTE>& array, VARIANT& vtResult) 
{ 
SAFEARRAY FAR* psarray; 
SAFEARRAYBOUND sabounds[1]; 

sabounds[0].lLbound=0; 
sabounds[0].cElements = (ULONG)array.GetSize(); 

long nLbound; 

psarray = SafeArrayCreate(VT_UI1, 1, sabounds); 
if(psarray == NULL) 
    return false; 

for(nLbound = 0; nLbound < (long)sabounds[0].cElements ; nLbound++){ 
    if(FAILED(SafeArrayPutElement(psarray, &nLbound, &array[nLbound]))){ 
     SafeArrayDestroy(psarray); 
     return false; 
    } 
} 

VariantFree(vtResult); 
vtResult.vt = VT_ARRAY|VT_UI1; 
vtResult.parray = psarray; 
return true; 
} 
+0

धन्यवाद - मुझे CComSafeArray नामक एक बहुत उपयोगी एटीएल क्लास मिला जो इसे बहुत आसान बनाता है (एमएफसी के पुराने संस्करण COLESafeArray का उपयोग कर सकते हैं)। – Rob

0

safearrays का उपयोग करके देखें। Safearrays उपयोग करने के लिए बहुत आसान कर रहे हैं

SAFEARRAY एक प्रकार

[id(1), helpstring("LogCache")] HRESULT LogCache([out,retval] VARIANT* logCache); 

के सूचक के रूप दिया जाता है: यहां कुछ उदाहरण कोड है। यहाँ कुछ उदाहरण कोड है जो किसी अनुप्रयोग का नवीनतम 1000 लॉग संदेशों की एक कैश है:

safearray_t<bstr_t> m_logCache; 
    ... 
    if (m_logCache.size() > 1000) 
    { 
     m_logCache.pop_back(); 
    } 

    m_logCache.push_front(Msg.str(), 0); 


    variant_t LogCache() 
    { 
     if (!m_logCache.is_empty()) 
     { 
      variant_t cache(m_logCache); 
      return cache; 
     } 
    } 

ध्यान रखें कि आपके मामले में वाक्य रचना लगभग निश्चित रूप से के बाद से मैं comet COM library उपयोग कर रहा हूँ अलग होने जा रहा है, लेकिन विचारों/अवधारणाएं वही हैं।

-1

आप बाइट्स की एक सरणी पारित करने के लिए BSTR उपयोग कर सकते हैं।

BYTE array[buffer_size]; 
... 
BSTR toBePassed = SysAllocStringByteLen((OLECHAR*)array,length); 
YourCOMMethod(toBePassed); 
SysFreeString(toBePassed); 

अपने विधि में:

BYTE* pData = (BYTE*)bstrPassed; 
DWORD dataLength = SysStringByteLen(bstrPassed); 
+4

इसे मत करो। सरणी सामग्री को उनके एएनएसआई कोड पेज से यूनिकोड या इसके विपरीत में अनुवादित किया जा सकता है, जिससे बाइनरी मान बदल सकते हैं। क्लाइंट एप्लिकेशन हमेशा यह नहीं जानते कि यह कब होता है, और वे अपने डेटा को दूषित कर पाएंगे। –

+2

स्पष्टीकरण के लिए: भले ही प्रोग्रामर बाइनरी डेटा रखने के लिए सरणी का इरादा रखता है, फिर भी विभिन्न सिस्टम दिनचर्या प्रोग्रामर के इरादे को नहीं जानते हैं। BSTRs को यूनिकोड तारों को पकड़ने के लिए डिज़ाइन किया गया है, और सिस्टम दिनचर्या उस धारणा को बनाएगी। –

2

SAFEARRAYs जाना अगर आप OLE-स्वचालन अनुपालन चाहते हैं, और हो सकता है इस तरह के VB6 के रूप में अन्य भाषाओं से COM इंटरफ़ेस का उपयोग कर सकते हैं। लेकिन वहाँ उदाहरण के लिए आईडीएल में एक विकल्प है,: -

void Fx([in] long cItems, [in, size_is(cItems)] BYTE aItems[]); 

यह एक तरीका है जहाँ मार्शलिंग कोड अनुमान लगा सकते हैं बाइट की संख्या पहले पैरामीटर का मान निरीक्षण से स्थानांतरित किया जाना है वर्णन करता है।

यह ठीक है, तो अपने ग्राहकों को सभी सी/C++ लिखा जाता है, लेकिन मैं लगता कि संभवतः एक युक्त इस स्वचालन अनुरूप नहीं होगा, VB6 से तो प्रयोग करने योग्य नहीं इंटरफेस, और मानक marshaler नहीं होगा मार्शलिंग करने में सक्षम हो, इसलिए आपको आईडीएल से अपना प्रॉक्सी/स्टब डीएलएल उत्पन्न करना होगा। करना मुश्किल नहीं है, लेकिन सुरक्षा का उपयोग करने से थोड़ा कठिन है।

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