2010-04-02 14 views
5

मैं एक विधि मुझे DLL से आयात करना चाहते हैं और इसके बारे में एक हस्ताक्षर है:DllImport और चार *

BOOL GetDriveLetter(OUT char* DriveLetter) 

मैं

[DllImport("mydll.dll")] 
    public static extern bool GetDriveLetter(byte[] DriveLetter); 

और

[DllImport("mydll.dll")] 
    public static extern bool GetDriveLetter(StringBuilder DriveLetter); 
की कोशिश की है

लेकिन ड्राइव लिटर चर में कुछ भी नहीं लौटा।

उत्तर

6

ऐसा लगता है कि फ़ंक्शन GetDriveLetterchar* की अपेक्षा कर रहा है जो ड्राइव अक्षर को रखने के लिए पर्याप्त स्मृति को इंगित करता है।

मुझे लगता है कि इस समस्या से संपर्क करना सबसे आसान तरीका है एक कच्चे IntPtr गुजरती हैं और एक API जो एक string को संसाधन प्रबंधन और रूपांतरण का ख्याल रखता है में GetDriveLetter के लिए कॉल रैप करने के लिए है।

[return:MarshalAsAttribute(UnmanagedType.Bool)] 
private static extern bool GetDriveLetter(IntPtr ptr); 

public static bool GetDriveLetter(out string drive) { 
    drive = null; 
    var ptr = Marshal.AllocHGlobal(10); 
    try { 
    var ret = GetDriveLetter(ptr); 
    if (ret) { 
     drive = Marshal.PtrToStringAnsi(ptr); 
    } 
    return ret; 
    } finally { 
    Marshal.FreeHGlobal(ptr); 
    } 
} 
+0

UnmanagedType.I1 का क्या अर्थ है? – Malfist

+0

@ माफिस्ट, मान I1 सीएलआर को 1 बाइट पूर्णांक के रूप में मान को मार्शल करने के लिए कहता है। यह वास्तव में इस नमूने में गलत था क्योंकि I4 सही मान है (थोड़ा पहले अपडेट किया गया था)। इस ब्लॉग एंट्री की जांच क्यों करें मैंने मार्शलिंग बूल वैल्यू पर लिखा था: http://blogs.msdn.com/jaredpar/archive/2008/10/14/pinvoke-and-bool-or-should-i-say-bool .aspx – JaredPar

+0

जब मैं इसे I4 बना देता हूं, तो मुझे मार्शल डायरेक्टिव एक्सेप्शन – Malfist

0

StringBuilder शायद जाने का रास्ता है, लेकिन आप समारोह कॉल करने से पहले स्ट्रिंग बिल्डर की क्षमता सेट करना होगा। चूंकि सी # को पता नहीं है कि GetDriveLeter कितनी मेमोरी का उपयोग करेगा, आपको यह सुनिश्चित करना होगा कि स्ट्रिंगबिल्डर के पास पर्याप्त जगह है। इसके बाद मार्शलर उस लंबाई तक आवंटित char* पास करेगा और इसे स्ट्रिंगबिल्डर पर वापस कर देगा।

[return:MarshalAsAttribute(UnmanagedType.I4)] 
private static extern bool GetDriveLetter(StringBuilder DriveLetter); 

public static bool GetDriveLetter(out string driverLetter) { 
    StringBuilder buffer = new StringBuilder(10); 
    bool ret = GetDriveLetter(buffer); 
    driveLetter = buffer.ToString(); 
    return ret; 
} 

उदाहरण के लिए p/invoke sample for GetWindowText() देखें।

+0

स्वीकृत उत्तर के विपरीत, सही स्ट्रिंग वापस नहीं करता है। – Malfist

+0

क्या होगा यदि आप DllImport विशेषता में CharSet = CharSet.Ansi जोड़ते हैं? यही कारण है कि आप देखभाल करते हैं क्योंकि आपके पास एक समाधान समाधान है। – shf301

+0

DllImport में CharSet.Ansi जोड़ने से कोई फर्क नहीं पड़ता। – Malfist

0
[DllImport("mydll.dll")] 
public static extern bool GetDriveLetter([MarshalAs(UnmanagedType.LPStr)] string DriveLetter) 
संबंधित मुद्दे