2010-04-15 4 views
19

में "अप्रबंधित" मेमोरी आवंटित करना मैं सी #+ में एक प्रोग्राम लिख रहा हूं जो सी ++ लाइब्रेरी का उपयोग करता है, और किसी कारण से मुझे इसे अप्रबंधित बफर आवंटित करने की आवश्यकता है। क्या सी # में ऐसा करने का कोई तरीका है? असल में मैं सिर्फ सी # में एक malloc क्या करने की जरूरत है ...सी #

धन्यवाद

+0

'नया बाइट [1024]' के बारे में क्या? –

+2

@ जॉन सॉंडर्स: मुझे नहीं पता कि यह विश्वसनीय होगा क्योंकि प्रबंधित स्मृति को संगत होने की गारंटी नहीं है। जीसी को इस्तेमाल होने के दौरान इसे आगे बढ़ने से रोकने के लिए आप इसे भी नीचे पिन करना चाहते हैं। – Joshua

+4

@ जोशुआ हुह? प्रबंधित स्मृति को संगत होने की बहुत गारंटी है। यह एक ही स्थान पर रहने की गारंटी नहीं है, लेकिन जब ऐसा होता है, तो यह संगत होता है, और इसे स्थिर रखने के लिए 'निश्चित' होता है। –

उत्तर

35

कुछ इस तरह का प्रयास करें:

आवंटित स्मृति:

using System; 
using System.Runtime.InteropServices; 

class Example 
{ 
    static void Main() 
    { 
     IntPtr pointer = Marshal.AllocHGlobal(1024); 
    } 
} 

यह Marshal.AllocHGlobal विधि का उपयोग करता निर्दिष्ट बाइट्स का उपयोग करके प्रक्रिया की अप्रबंधित स्मृति से।

+19

सुनिश्चित करें कि आप इसे 'FreeHGlobal() 'से मुक्त करें। अपवाद सुरक्षित होने के लिए आप शायद स्मृति को आवंटित करने के लिए 'आईडीस्पोजेबल' रैपर क्लास बनाना चाहते हैं ताकि आप 'निपटान' पर स्मृति मुक्त करने के लिए 'उपयोग' कथन में आवंटित कर सकें। –

7

आप इसके लिए बाइट सरणी भी उपयोग कर सकते हैं। और एक महत्वपूर्ण यह है - - है कि SomeUnmanagedFunction कि सूचक को छूने के लिए अनुमति नहीं है के बाद यह वापस आ गया है और कोड

static unsafe void PerformOperation() 
{ 
    byte[] buf = new byte[1024]; 
    fixed (void* ptr = &buf[0]) 
    { 
     SomeUnmanagedFunction(new IntPtr(ptr)); 
    } 
} 

मुद्दा:

आप एक असुरक्षित दिनचर्या और फिक्स्ड बयान का उपयोग करके ऐसा निश्चित ब्लॉक से बाहर निकला है। तो यदि आप ऐसा कुछ करते हैं:

static void PerformFabulousTrick() 
{ 
    byte[] buf = new byte[1024]; 
    fixed (void *ptr = &buf[0]) 
    { 
     SetBuffer(ptr, buf.Length); 
    } 
    FillBuffer(); // puts data in buf - NOT - may crash hard 
} 

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

सामान्य रूप से, मैं यह सुनिश्चित करने की अनुशंसा करता हूं कि आप फ़ंक्शन में सही ढंग से P/Invoking कर रहे हैं ताकि शायद मार्शलर आपके लिए यह काम कर सके। मुझे ग्लोबल अलाक से बेहतर तय करना पसंद है क्योंकि इसका दायरा स्पष्ट है। मैं तय नहीं कर सकता कि मुझे कम से कम ग्लोबल अलाक और जीसीएचंडल पसंद है। दोनों को की आवश्यकता है क्योंकि आप अधिक काम करने के लिए जीसी या भाषा आपके लिए नहीं करेंगे।

2

इस प्रकार हमें बाइट्स की विशिष्ट संख्या का उपयोग करके अप्रबंधित स्मृति को असाइन और मुक्त करने की आवश्यकता है।

// Demonstrate how to call GlobalAlloc and 
// GlobalFree using the Marshal class. 
IntPtr hglobal = Marshal.AllocHGlobal(100); 
Marshal.FreeHGlobal(hglobal)