You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1.2 KiB
43 lines
1.2 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
|
|
public abstract class CallbackHandler<THandler>
|
|
where THandler: CallbackHandler<THandler>
|
|
{
|
|
private GCHandle selfHandle;
|
|
private GCHandle callbacksHandle;
|
|
|
|
public IntPtr ContextPtr => GCHandle.ToIntPtr(selfHandle);
|
|
|
|
public IntPtr CallbacksPtr => callbacksHandle.AddrOfPinnedObject();
|
|
|
|
protected CallbackHandler()
|
|
{
|
|
selfHandle = GCHandle.Alloc(this);
|
|
}
|
|
|
|
public virtual void Destroy()
|
|
{
|
|
if (callbacksHandle.IsAllocated)
|
|
callbacksHandle.Free();
|
|
|
|
selfHandle.Free();
|
|
}
|
|
|
|
protected IntPtr CreateCallback<TDelegate>(TDelegate callback)
|
|
{
|
|
return Marshal.GetFunctionPointerForDelegate(callback);
|
|
}
|
|
|
|
protected void RegisterCallbacks<TCallbacks>(TCallbacks callbacks)
|
|
{
|
|
// Pin the callbacks struct so that native code can safely keep a pointer to it and re-use it on subsequent calls
|
|
callbacksHandle = GCHandle.Alloc(callbacks, GCHandleType.Pinned);
|
|
}
|
|
|
|
protected static THandler GetSelf(IntPtr target)
|
|
{
|
|
return (THandler)GCHandle.FromIntPtr(target).Target;
|
|
}
|
|
}
|