2009-05-07 12 views
6

से पासिंग संकेत मैं एक सी # परियोजना है कि एक सी dll आयात करता है, dll इस समारोह है। मुझे वास्तव में धारावाहिक पैरामीटर के एक चरित्र को वापस करने के लिए मिला है, लेकिन मुझे सच में यकीन नहीं है कि मैं क्या कर रहा हूं और यह समझना चाहता हूं कि क्या हो रहा है, और निश्चित रूप से यह काम कर रहा है।अप्रबंधित कोड

तो, मुझे पूरा यकीन है कि डीएलएल का उपयोग किया जा रहा है, पॉइंटर्स के बिना अन्य कार्य ठीक काम करते हैं। मैं पॉइंटर्स कैसे संभाल सकता हूं? क्या मुझे इसे मार्शल करना है? हो सकता है कि मुझे डेटा डालने के लिए एक निश्चित जगह होनी चाहिए?

एक स्पष्टीकरण बहुत अच्छा होगा।

धन्यवाद! रिचर्ड

उत्तर

8

आपको एक इंटिप्टर और मार्शल का उपयोग करना होगा जो कि सी # संरचना में इंटप्राट जिसे आप इसे रखना चाहते हैं। अपने मामले में आपको इसे int [] पर मार्शल करना होगा।

यह कई चरणों में किया जाता है:

  • एक अप्रबंधित संभाल आवंटित
  • कॉल unamanged सरणी
  • साथ समारोह सरणी int करने के लिए
  • Convert बाइट सरणी में कामयाब बाइट सरणी सरणी में कनवर्ट करें
  • रिलीज अप्रबंधित संभाल

कि कोड आप यह अनुमान लगा देना चाहिए:

// The import declaration 
[DllImport("Library.dll")] 
public static extern int primary_read_serial(int, ref int, IntPtr, int) ; 


// Allocate unmanaged buffer 
IntPtr serial_ptr = Marshal.AllocHGlobal(length * sizeof(int)); 

try 
{ 
    // Call unmanaged function 
    int return_code; 
    int result = primary_read_serial(handle, ref return_code, serial_ptr, length); 

    // Safely marshal unmanaged buffer to byte[] 
    byte[] bytes = new byte[length * sizeof(int)]; 
    Marshal.Copy(serial_ptr, bytes, 0, length); 

    // Converter to int[] 
    int[] ints = new int[length]; 
    for (int i = 0; i < length; i++) 
    { 
     ints[i] = BitConverter.ToInt32(bytes, i * sizeof(int)); 
    } 

} 
finally 
{ 
    Marshal.FreeHGlobal(serial_ptr); 
} 

भूल मत कोशिश अंत में, या आप अप्रबंधित संभाल लीक का जोखिम होगा।

+0

विशेष रूप से, एक अप्रबंधित सरणी और एक प्रबंधित int [] और मार्शल आवंटित करें। अपने IntPtr को अप्रबंधित सरणी से प्रबंधित प्रबंधित करें। –

+1

कोशिश करें या अंत में कोशिश करें? – MedicineMan

+0

कोशिश करें अंततः, इसे इंगित करने के लिए धन्यवाद। फिक्स्ड। – Coincoin

0

जब आपके पी लेखन/आह्वान है कि समारोह की घोषणा, इस तरह सूचक मापदंडों के लिए कीवर्ड रेफरी का उपयोग करके देखें:

[DllImport("YouDll.dll", EntryPoint = "primary_read_serial")] 
public static extern int primary_read_serial(int, ref int, ref int, int) ; 

मुझे यकीन है कि अगर आप सी # में पैरामीटर 'नाम निर्दिष्ट करना होगा नहीं कर रहा हूँ। और याद रखें, उस विधि को कॉल करते समय, आपको संदर्भ द्वारा पारित तर्कों में रेफरी का भी उपयोग करना होगा।

+0

यदि यह एक सरणी होना चाहिए तो उसे एक इंटिप्टर और मार्शल के रूप में पास करना सुनिश्चित करना होगा। हालांकि एक प्रबंधित सरणी पर कॉपी करें। –

2

यदि मैं समझता हूं कि आप क्या करने की कोशिश कर रहे हैं, तो यह आपके लिए काम करना चाहिए।

unsafe 
{ 
    int length = 1024; // Length of data to read. 

    fixed (byte* data = new byte[length]) // Pins array to stack so a pointer can be retrieved. 
    { 
     int returnCode; 
     int retValue = primary_read_serial(0, &returnCode, data, length); 

     // At this point, `data` should contain all the read data. 
    } 
} 

JaredPar आप फिर भी यह करने के लिए आसान तरीका है, जो सिर्फ अपने बाहरी समारोह घोषणा को बदलने के लिए इतना है कि सी # पृष्ठभूमि में आपके लिए मार्शलिंग करता है देता है।

उम्मीद है कि यह आपको थोड़ा सा स्तर पर क्या हो रहा है इसका एक विचार देता है।

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