I have a C# project in which i use several unmanaged C++ functions.
More so, I also have static IntPtr that I use as parameters for those functions. I know that whenever I use them, I should implement IDisposable in that class and use a destructor to invoke the Dispose method, where I free the used IntPtr, as is said in the MSDN page.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
if (disposing)
{
component.Dispose();
}
CloseHandle(m_InstanceHandle);
m_InstanceHandle = IntPtr.Zero;
disposed = true;
}
}
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
However, when I terminate the application, I’m still left with a hanging process in TaskManager. I believe that it must be related to the used of the MarshalAs instruction in my structures:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SipxAudioCodec
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string CodecName;
public SipxAudioBandwidth Bandwidth;
public int PayloadType;
}
When I create such a structure should I also be careful to free the space it allocs using a destructor?
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct SipxAudioCodec
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string CodecName;
public SipxAudioBandwidth Bandwidth;
public int PayloadType;
~SipxAudioCodec()
{
Marshal.FreeGlobal(something...);
}
}
The proper way to handle
IntPtr-style handles in p/Invoke interop is:SafeMyHandlederived fromSafeHandle. It should only overrideIsInvalidandReleaseHandle, and do nothing else.MyHandlethat has methods for the public API for that handle.MyHandleshould have a private member of typeSafeMyHandle.MyHandleshould implementIDisposable, and itsDisposemethod should just callSafeMyHandle.Dispose.IntPtrdirectly; rather, they should pass and return instances ofSafeMyHandle. The one exception is the “freeing function” that is called fromSafeMyHandle.ReleaseHandle; it should take anIntPtr.If you follow these conventions, your handles will be freed even if your AppDomain is rudely torn down.