Ich bin Marshalling Daten über C/C# Grenze. Ich habe die folgende Struktur:Muss ich ein IntPtr innerhalb eines Callbacks freigeben?
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Message
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string From;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string Subject;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string Body;
}
Der Rückruf ist wie folgt definiert:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void MessageReceiveDelegate([In]IntPtr ptrToMessage);
private void MessageReceiveCallback(IntPtr ptrToMessage)
{
Message message = (Message)Marshal.PtrToStructure(ptrToMessage, typeof(Message));
Marshal.FreeHGlobal(ptrToMessage); //This throws COMException!
}
Meine Frage ist, kann ich IntPtr (ptrToMessage) über die Freigabe innerhalb des Rückrufs kümmern Speicherlecks zu vermeiden? Ich habe versucht Aufruf FreeHGlobal drauf, aber mit folgender Ausnahme am Ende:
‚System.Runtime.InteropServices.COMException‘ ist in mscorlib.dll aufgetreten
Weitere Informationen Eine nicht behandelte Ausnahme des Typs: Der Griff ist ungültig. (Ausnahme von HRESULT: 0x80070006 (E_HANDLE))
So bin ich entweder etwas falsch zu machen, oder der Speicher nicht von mir freigegeben werden.
Wenn Ihr Code nicht der Eigentümer des 'Intptr' ist (d. H. Ihn nicht zugeordnet hat), sollten Sie ihn nicht freigeben, es sei denn, die API dokumentiert dies. Es ist auch möglich, dass Sie eine andere "Marshal" -Methode verwenden müssen, um den Puffer wie "Marshal.FreeCoTaskMem" – GreatAndPowerfulOz
@ Great.And.Powerful.Oz zu befreien. Ich habe den IntPtr nicht zugewiesen. Es wird mir von der 3rd-Party-Bibliothek übergeben. Ich habe zuvor versucht, FreeCoTaskMem zu verwenden, aber das verursachte einen Absturz, anstatt nur eine Ausnahme. – Eternal21