संक्षिप्त शब्दों में प्रश्न यह है: प्रबंधित डीएलएल से प्रबंधित डीएलएल से प्रबंधित स्मृति में आईटीआरपीआरटी के रूप में वापस आने वाली मेमोरी कैसे मुक्त करें?प्रबंधित सी # से पॉइंटर के साथ प्रबंधित सी # से रिलीज अप्रबंधित स्मृति
विवरण: मान लें कि हमारे पास सरल कार्य है OUTPUT के रूप में दो पैरामीटर लेता है, पहला बाइट सरणी के लिए संदर्भ सूचक है और दूसरा संदर्भ संदर्भ है। फ़ंक्शन कुछ नियमों के आधार पर बाइट्स की मात्रा आवंटित करेगा और स्मृति के सूचक और बाइट्स के आकार और वापसी मूल्य (सफलता के लिए 1 और असफल होने के लिए 0) वापस करेगा।
नीचे कोड ठीक काम करता है और मैं बाइट सरणी सही ढंग से और बाइट्स की गिनती और वापसी मान प्राप्त कर सकते हैं, लेकिन जब मैं स्मृति सूचक का उपयोग कर (IntPtr) मुक्त करने की कोशिश मैं अपवाद:
विंडोज ने TestCppDllCall.exe में ब्रेकपॉइंट ट्रिगर किया है।
यह ढेर के भ्रष्टाचार के कारण हो सकता है, जो TestCppDllCall.exe में किसी भी बग को इंगित करता है या किसी भी डीएलएल को लोड किया गया है।
यह उपयोगकर्ता F12 दबाकर भी हो सकता है जबकि TestCppDllCall.exe पर ध्यान केंद्रित किया गया है।
आउटपुट विंडो में अधिक नैदानिक जानकारी हो सकती है।
स्पष्ट बातें करने के लिए:
अगले सी # कोड अन्य DLL समारोह के साथ सही ढंग से काम एक ही हस्ताक्षर है और स्मृति को मुक्त कराने के किसी भी समस्या के बिना काम करता है।
यदि आपको आवंटन मेमोरी विधि बदलने या किसी अन्य कोड को जोड़ने की आवश्यकता है तो (सी) कोड में कोई भी संशोधन स्वीकार किया जाता है।
मुझे आवश्यक सभी कार्यक्षमता मूल डीएलएल फ़ंक्शन संदर्भ द्वारा दो पैरामीटर (बाइट सरणी और int, सी # [बाइट सरणी और int के इंटपट्रेट] स्वीकार करते हैं) कुछ नियमों के आधार पर उन्हें कुछ मानों के साथ भरें और फ़ंक्शन परिणाम लौटाएं (सफलता या विफल)।
CppDll.h
#ifdef CPPDLL_EXPORTS
#define CPPDLL_API __declspec(dllexport)
#else
#define CPPDLL_API __declspec(dllimport)
#endif
extern "C" CPPDLL_API int writeToBuffer(unsigned char *&myBuffer, int& mySize);
CppDll।सीपीपी
#include "stdafx.h"
#include "CppDll.h"
extern "C" CPPDLL_API int writeToBuffer(unsigned char*& myBuffer, int& mySize)
{
mySize = 26;
unsigned char* pTemp = new unsigned char[26];
for(int i = 0; i < 26; i++)
{
pTemp[i] = 65 + i;
}
myBuffer = pTemp;
return 1;
}
सी # कोड:
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace TestCppDllCall
{
class Program
{
const string KERNEL32 = @"kernel32.dll";
const string _dllLocation = @"D:\CppDll\Bin\CppDll.dll";
const string funEntryPoint = @"writeToBuffer";
[DllImport(KERNEL32, SetLastError = true)]
public static extern IntPtr GetProcessHeap();
[DllImport(KERNEL32, SetLastError = true)]
public static extern bool HeapFree(IntPtr hHeap, uint dwFlags, IntPtr lpMem);
[DllImport(_dllLocation, EntryPoint = funEntryPoint, CallingConvention = CallingConvention.Cdecl)]
public static extern int writeToBuffer(out IntPtr myBuffer, out int mySize);
static void Main(string[] args)
{
IntPtr byteArrayPointer = IntPtr.Zero;
int arraySize;
try
{
int retValue = writeToBuffer(out byteArrayPointer, out arraySize);
if (retValue == 1 && byteArrayPointer != IntPtr.Zero)
{
byte[] byteArrayBuffer = new byte[arraySize];
Marshal.Copy(byteArrayPointer, byteArrayBuffer, 0, byteArrayBuffer.Length);
string strMyBuffer = Encoding.Default.GetString(byteArrayBuffer);
Console.WriteLine("Return Value : {0}\r\nArray Size : {1}\r\nReturn String : {2}",
retValue, arraySize, strMyBuffer);
}
}
catch (Exception ex)
{
Console.WriteLine("Error calling DLL \r\n {0}", ex.Message);
}
finally
{
if (byteArrayPointer != IntPtr.Zero)
HeapFree(GetProcessHeap(), 0, byteArrayPointer);
}
Console.ReadKey();
}
}
}
मुझे इस कोड मैं सेट लाइन में बिंदु को तोड़ने डिबग (वापसी 1) और बफर के मूल्य था:
myBuffer = 0x031b4fc0 "ABCDEFGHIJKLMNOPQRSTUVWXYZ««««««««î"
और मुझे सी # कोड में वही मान मिला जब फ़ंक्शन कॉल रिटर्न और मान था:
52121536
परिणाम मुझे सही मेमोरी पॉइंटर मिला और मैं बाइट सरणी मान प्राप्त करने में सक्षम हूं, इस पॉइंटर के साथ इन मेमोरी ब्लॉक को सी # में कैसे मुक्त किया जाए?
कृपया मुझे बताएं कि क्या कुछ स्पष्ट नहीं है या यदि कोई टाइपो है, तो मैं मूल अंग्रेजी स्पीकर नहीं हूं।
आपकी त्वरित प्रतिक्रिया के लिए धन्यवाद। मुझे उम्मीद थी कि सी # में अप्रबंधित स्मृति को मुक्त करने का एक तरीका है। – khaled
मैं dasblinkenlight से सहमत हूं: * सबसे साफ * तरीका आपके .dll में "मुक्त" विधि जोड़ने के लिए तर्कसंगत है। लेकिन पीटर रिची भी सही है: सी # आवंटित (उदाहरण के लिए 'CoTaskMemAlloc() ') के लिए सी # # (" इंटरऑप के माध्यम से) एक "मुक्त" (उदा।' फ्रीकोटास्कम() ') के लिए निश्चित रूप से संभव है। एक चीज जो आप * सी # से नहीं कर सकते, "हटाएं" है, अगर। डीएल एक सी ++ "नया" करता है। "मॉलोक/फ्री": ठीक है। CoTaskMemAlloc/FreeCoTaskMem: भी ठीक है। "नया/मुफ्त": निश्चित रूप से * नहीं *। – paulsm4
@ paulsm4 कृपया बताएं कि सी # मॉलोक/मुफ्त में कैसे आना है? – awattar