I call the following VC ++ method
__declspec(dllexport) unsigned char* Get_Version_String()
from C # as follows:
internal static class NativeMethods { [DllImport("my.dll"), CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true, CallingConvention = CallingConvention.Cdecl)] internal static extern string Get_Version_String(); }
The above code is in the library which is for .NET 3.5. When I call this from assembly 3.5, it works fine; however, calling it from assembly 4.5, this leads to
0xC0000374: heap is corrupted
After reading this question , I changed my method calls as follows:
[DllImport("my.dll", EntryPoint = "Get_Version_String", CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr Get_Version_String_PInvoke(); internal static string Get_Version_String() { IntPtr ptr = Get_Version_String_PInvoke(); string versionString = Marshal.PtrToStringAnsi(ptr); return versionString; }
This works as expected, but the response from Hans Passant comes with a warning:
The workaround you found is correct; the marshaller is not going to release memory for IntPtr . Note that this only actually comes to an end if the C code returns a const char* that does not need to be released. If this is not the case, you have a persistent memory leak.
Since the C ++ method does not return const , I proceed from the assumption that a workaround for my specific function will lead to a memory leak.
I cannot change the original method, so I found this other question that discusses how to free memory from coordinated code. However, calling either Marshal.FreeHGlobal(ptr) or Marshal.FreeCoTaskMem(ptr) also throw 0xC0000374: A heap has been corrupted.
Can anyone
a) confirm that such a method will indeed suffer from a memory leak and
b) if so, suggest freeing up memory from a pointer in managed code?
The body of the C ++ method is simplified as follows:
unsigned char versionString[50]; __declspec(dllexport) unsigned char* Get_Version_String() { strcpy((char *) versionString, "Key1:[xx],Key2:[xx],Key3:[xx],Key4:[xx]");
Thanks in advance, and sorry if this is trivial; I am neither a C ++ nor an Interop expert.