2009-06-28 14 views
8

मैं इस परिदृश्य के साथ आपकी मदद की जरूरत अप्रबंधित सी ++ DLL को MemoryStream डेटा पास कर सकते हैं:मैं कैसे का उपयोग कर पी/आह्वान

मैं एक MemoryStream (सी #) में हार्डवेयर से कुछ डेटा पढ़ रहा हूँ और मैं इस डेटा पास करनी होगी स्मृति में एक डीएल को अप्रबंधित सी ++ में लागू किया गया (सूचक का उपयोग कर ??)। डेटा पढ़ने (स्ट्रीम में) बहुत बड़ा (मेगाबाइट्स) है। मैं समझता हूँ कि मैं पी/इस dll आह्वान कर सकते हैं लेकिन क्या मुझे यकीन है कि नहीं कर रहा हूँ कैसे सी ++ एपीआई को धारा डेटा का सूचक/संदर्भ पारित करने के लिए है?

मुझे स्वीकार करना होगा कि मैं उलझन में हूं क्योंकि मैं सी # के लिए नया हूं - क्या मुझे असुरक्षित/निश्चित उपयोग करने की आवश्यकता है क्योंकि डेटा बड़ा है या ये अप्रासंगिक हैं क्योंकि मेमोरीस्ट्रीम ऑब्जेक्ट जीसी द्वारा प्रबंधित किया जाता है? कुछ उदाहरण कोड/विस्तृत विवरण बहुत उपयोगी होगा। अप्रबंधित एपीआई के लिए धन्यवाद

हस्ताक्षर:

BOOL DoSomething (शून्य * rawData, पूर्णांक dataLength)

+0

सी ++ डीएल के लिए किस डेटा प्रकार की आवश्यकता होती है? – scottm

+0

इसे कच्चे डेटा की आवश्यकता है - बाइट/शून्य *। मैं आवश्यकतानुसार डीएलएल एपीआई बदल सकता हूं। –

उत्तर

12

यह सिर्फ उम्मीद कर रहा है, तो आप एक बाइट सरणी में MemoryStream पढ़ सकते हैं और उसके बाद करने के लिए है कि करने के लिए एक सूचक पारित बाइट प्रक्रिया।

[DllImport("mylibrary.dll", CharSet = CharSet.Auto)] 
public static extern bool doSomething(IntPtr rawData, int dataLength); 

फिर, एक बाइट सरणी में MemoryStream से बाइट्स पढ़ें:

आप बाहरी प्रणाली की घोषणा करने के लिए है। का आवंटन एक GCHandle जो:

एक बार आवंटित, आप एक GCHandle उपयोग कर सकते हैं से प्रबंधित वस्तु को रोकने के लिए कचरा द्वारा एकत्र किया जा रहा कलेक्टर जब एक अप्रबंधित ग्राहक केवल संदर्भ रखती है। इस तरह के एक हैंडल के बिना, वस्तु से पहले अप्रबंधित ग्राहक की ओर से अपने काम को पूरा करने कचरा कलेक्टर द्वारा एकत्र किया जा सकता है।

और अंत में, C++ dll को पास करने के लिए IntPtr प्राप्त करने के लिए AddrOfPinnedObject विधि का उपयोग करें।

private void CallTheMethod(MemoryStream memStream) 
{ 
    byte[] rawData = new byte[memStream.Length]; 
    memStream.Read(rawData, 0, memStream.Length); 

    GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned); 
    IntPtr address = handle.AddrOfPinnedObject(); 

    doSomething(address, rawData.Length); 
    rawDataHandle.Free(); 
} 
+0

धन्यवाद। हां यह विधि मूल रूप से संपीड़न के लिए है, इसलिए इसे पास किए गए कच्चे डेटा की आवश्यकता/संचालन की आवश्यकता होगी। भी उत्सुक असुरक्षित टैग किए गए डेटा को सी # में ढेर या ढेर पर रखा गया है? –

+0

यह कोड के समान है जो असुरक्षित चिह्नित नहीं है। – scottm

+0

बस स्पष्ट करने के लिए, इस कोड को असुरक्षित नहीं माना जाता है। – scottm

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