diff --git a/Libs/GObject/Classes/ClosureHelper.cs b/Libs/GObject/Classes/ClosureHelper.cs index 2056ecb46..95bfe1d88 100644 --- a/Libs/GObject/Classes/ClosureHelper.cs +++ b/Libs/GObject/Classes/ClosureHelper.cs @@ -12,6 +12,10 @@ internal class ClosureHelper : IDisposable private static readonly Dictionary Handlers = new Dictionary(); + // We need to store a reference to MarshalCallback to + // prevent the delegate from being collected by the GC + private readonly ClosureMarshal _marshalCallback; + private bool _disposedValue; private readonly Action? _callback; private readonly ActionRefValues? _callbackRefValues; @@ -41,7 +45,8 @@ public ClosureHelper(Object obj, ActionRefValues callbackRefValues) : this(obj) private ClosureHelper(Object obj) { Handle = Closure.Native.new_object((uint) Marshal.SizeOf(typeof(Closure)), obj.Handle); - Closure.Native.set_marshal(Handle, MarshalCallback); + _marshalCallback = MarshalCallback; + Closure.Native.set_marshal(Handle, _marshalCallback); } ~ClosureHelper() => Dispose(false); @@ -50,12 +55,12 @@ private ClosureHelper(Object obj) #region Methods - private void MarshalCallback(IntPtr closure, ref Value return_value, uint n_param_values, - Value[] param_values, IntPtr invocation_hint, IntPtr marshal_data) + private void MarshalCallback(IntPtr closure, ref Value returnValue, uint nParamValues, + Value[] paramValues, IntPtr invocationHint, IntPtr marshalData) { _callback?.Invoke(); - _callbackRefValues?.Invoke(ref param_values); + _callbackRefValues?.Invoke(ref paramValues); } public static bool TryGetByDelegate(Action action, out ClosureHelper closure) diff --git a/Libs/GObject/Classes/Object.cs b/Libs/GObject/Classes/Object.cs index c11ce0bc6..09960785a 100644 --- a/Libs/GObject/Classes/Object.cs +++ b/Libs/GObject/Classes/Object.cs @@ -27,6 +27,10 @@ public partial class Object : INotifyPropertyChanged, IDisposable #region Properties protected internal IntPtr Handle { get; private set; } + + // We need to store a reference to WeakNotify to + // prevent the delegate from being collected by the GC + private WeakNotify? _onFinalized; protected bool Disposed { get; private set; } @@ -135,7 +139,11 @@ protected virtual void Initialize() { } // Modify this in the future to play nicely with virtual function support? private void OnFinalized(IntPtr data, IntPtr where_the_object_was) => Dispose(); - private void RegisterOnFinalized() => Native.weak_ref(Handle, OnFinalized, IntPtr.Zero); + private void RegisterOnFinalized() + { + _onFinalized = OnFinalized; + Native.weak_ref(Handle, _onFinalized, IntPtr.Zero); + } private void RegisterProperties() { @@ -182,9 +190,7 @@ private void RegisterEvent(string eventName, ClosureHelper closure, bool after) if (ret == 0) throw new Exception($"Could not connect to event {eventName}"); - // Add to our closures list so the callback - // doesn't get garbage collected. - // closures.Add(closure); + // Add to our closures list so the callback doesn't get garbage collected. Closures[closure] = ret; }