using System; using System.Collections.Generic; using System.Runtime.InteropServices; public abstract class CallbackHandler where THandler: CallbackHandler { private GCHandle selfHandle; private GCHandle callbacksHandle; public IntPtr ToIntPtr => callbacksHandle.AddrOfPinnedObject(); protected IntPtr SelfPtr => GCHandle.ToIntPtr(selfHandle); protected CallbackHandler() { selfHandle = GCHandle.Alloc(this); } public void Destroy() { if (callbacksHandle.IsAllocated) callbacksHandle.Free(); selfHandle.Free(); } protected IntPtr CreateCallback(TDelegate callback) { return Marshal.GetFunctionPointerForDelegate(callback); } protected void RegisterCallbacks(TCallbacks callbacks) { callbacksHandle = GCHandle.Alloc(callbacks, GCHandleType.Pinned); } protected static THandler GetSelf(IntPtr target) { return (THandler)GCHandle.FromIntPtr(target).Target; } }