using System; using System.Runtime.InteropServices; namespace Developpez.Dotnet { /// /// Représente un pointeur non managé qui implémente IDisposable pour libérer la ressource. /// public class DisposablePointer : IDisposable { /// /// Initialise une nouvelle instance de DisposablePointer, avec la valeur spécifiée et /// l'action spécifiée pour libérer le pointeur. /// /// Valeur initiale du pointeur /// Action à exécuter pour libérer le pointeur public DisposablePointer(IntPtr value, Action disposeAction) { this._value = value; this._disposeAction = disposeAction; } private bool _disposed = false; private readonly IntPtr _value; private Action _disposeAction; /// /// Renvoie la valeur du pointeur /// /// L'objet a été disposé et le pointeur libéré public IntPtr Value { get { if (_disposed) throw new ObjectDisposedException("DisposablePointer"); return _value; } } /// /// Libère la ressource représentée par le pointeur, en appelant l'action spécifiée /// en paramètre du constructeur /// public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } /// /// Destructeur /// ~DisposablePointer() { this.Dispose(false); } /// /// Libère la ressource représentée par le pointeur, en appelant l'action spécifiée /// en paramètre du constructeur /// /// Inutilisé protected virtual void Dispose(bool disposing) { if (_disposeAction != null && _value != IntPtr.Zero) _disposeAction(_value); _disposed = true; } #if !SILVERLIGHT // Marshal.AllocHGlobal n'est pas supporté en SL /// /// Alloue la quantité spécifiée de mémoire non managée, et renvoie le pointeur obtenu /// sous forme d'un DisposablePointer. /// /// Quantité de mémoire à allouer /// Un DisposablePointer représentant la zone mémoire allouée public static DisposablePointer AllocHGlobal(int size) { return new DisposablePointer(Marshal.AllocHGlobal(size), Marshal.FreeHGlobal); } #endif /// /// Méthode d'extension qui crée un wrapper IDisposable pour un pointeur /// /// Le pointeur à wrapper /// L'action à effectuer pour libérer la ressource /// Un objet IDisposable qui wrappe le pointeur public static DisposablePointer AsDisposable(IntPtr value, Action disposeAction) { return new DisposablePointer(value, disposeAction); } } }