मैं सी # में अप्रबंधित डीएलएल आयातों के मार्शलिंग के बारे में सीख रहा हूं ... और मैं कुछ ऐसी चीज में आया हूं जो मुझे समझ में नहीं आता है।सी # से डेल्फी डीएलएल रिटर्न स्ट्रिंग ... .NET 4.5 हीप भ्रष्टाचार लेकिन .NET 4.0 काम करता है? कृपया समझाईए?
डेल्फी में, वहाँ है कि एक Procedure SomeFunc() : PChar; Stdcall;
मेरी समझ से से Result := NewStr(PChar(somestring))
लौटा रहा है एक समारोह है, NewStr सिर्फ स्थानीय ढेर पर एक बफर आवंटित ... और SomeFunc इसे करने के लिए एक सूचक लौटा रहा है।
.NET 4.0 (ग्राहकों का प्रोफाइल) में, सी # के माध्यम से मैं उपयोग कर सकते हैं:
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern String SomeFunc(uint ObjID);
यह काम करता है (या के रूप में डेविड कहते हैं, "काम करने के लिए प्रकट होता है") विंडोज 7 .NET 4.0 ग्राहकों का प्रोफाइल में ठीक। विंडोज 8 में, यह अप्रत्याशित व्यवहार है, जिसने मुझे इस रास्ते से नीचे लाया।
तो मैंने .NET 4.5 में एक ही कोड को आजमाने का फैसला किया और ढेर भ्रष्टाचार त्रुटियों को प्राप्त किया। ठीक है, तो अब मुझे पता है कि यह चीजों को करने का सही तरीका नहीं है। तो मैं आगे खुदाई:
फिर भी .NET 4.5 में
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr _SomeFunc();
public static String SomeFunc()
{
IntPtr pstr = _SomeFunc();
return Marshal.PtrToStringAnsi(pstr);
}
यह बिना किसी बाधा के काम करता है। मेरी (नौसिखिया) चिंता यह है कि न्यूएसआरटी() ने इस स्मृति को आवंटित किया है और यह हमेशा के लिए बस बैठा है। क्या मेरी चिंता वैध नहीं है? तथापि
[DllImport("SomeDelphi.dll", EntryPoint = "SomeFunc", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr _SomeFunc();
public static String SomeFunc()
{
String str;
IntPtr pstr = _SomeFunc();
str = Marshal.PtrToStringAnsi(pstr);
Marshal.FreeCoTaskMem(pstr);
return str;
}
इस कोड को 4.5 में एक ही ढेर अपवाद फेंकता है,:
.NET 4.0 में, मैं भी ऐसा कर सकते हैं और यह एक अपवाद कभी नहीं फेंकता है। इससे मुझे विश्वास होता है कि समस्या इस तथ्य में निहित है कि .NET 4.5 में, मार्शलर FreeCoTaskMem() की कोशिश कर रहा है और यही अपवाद फेंक रहा है।
तो सवाल:
क्यों नेट 4.0 में यह काम करते हैं और नहीं 4.5 करता है?
क्या मुझे मूल डीएलएल में न्यूएसआरटी() के आवंटन के बारे में चिंतित होना चाहिए?
यदि उत्तर "नहीं" # 2 का उत्तर है, तो दूसरा कोड उदाहरण मान्य है?
रिकॉर्ड के लिए, यह वही मशीन, एक ही ओएस, एक ही कंपाइलर, वही सब कुछ है। बस प्रोजेक्ट पर राइट क्लिक करें -> फ्रेमवर्क को 4.5 और व्हायोला में बदलें, यह क्रैश हो जाता है। वैसे भी, मुझे खुशी है कि मैं इसे सही ढंग से समझ रहा था, और हमेशा आपकी मदद के लिए धन्यवाद। –