コード例 #1
0
ファイル: GObject.cs プロジェクト: kleisauke/net-vips
        /// <summary>
        /// Connects a callback function (<paramref name="callback"/>) to a signal on this object.
        /// </summary>
        /// <remarks>
        /// The callback will be triggered every time this signal is issued on this instance.
        /// </remarks>
        /// <param name="detailedSignal">A string of the form "signal-name::detail".</param>
        /// <param name="callback">The callback to connect.</param>
        /// <param name="data">Data to pass to handler calls.</param>
        /// <returns>The handler id.</returns>
        /// <exception cref="T:System.Exception">If it failed to connect the signal.</exception>
        public uint SignalConnect(string detailedSignal, Delegate callback, IntPtr data = default)
        {
            if (callback is Image.EvalDelegate evalDelegate)
            {
                void EvalMarshal(IntPtr imagePtr, IntPtr progressPtr, IntPtr userDataPtr)
                {
                    if (progressPtr == IntPtr.Zero || imagePtr == IntPtr.Zero)
                    {
                        return;
                    }

                    using var image = new Image(imagePtr);
                    image.ObjectRef();

                    var progressStruct = progressPtr.Dereference <VipsProgress>();

                    evalDelegate.Invoke(image, progressStruct);
                }

                callback = (VipsImage.EvalSignal)EvalMarshal;
            }

            // add a weak reference callback to ensure all handles are released on finalization
            if (_handles.Count == 0)
            {
                GWeakNotify notify       = ReleaseDelegates;
                var         notifyHandle = GCHandle.Alloc(notify);

                Internal.GObject.WeakRef(this, notify, GCHandle.ToIntPtr(notifyHandle));
            }

            // prevent the delegate from being re-located or disposed of by the garbage collector
            var delegateHandle = GCHandle.Alloc(callback);

            _handles.Add(delegateHandle);

            // get the pointer for the delegate which can be passed to the native code
            var callbackPtr = Marshal.GetFunctionPointerForDelegate(callback);
            var ret         = GSignal.ConnectData(this, detailedSignal, callbackPtr, data, null, default);

            if (ret == 0)
            {
                throw new Exception("Failed to connect signal.");
            }

            return(ret);
        }
コード例 #2
0
ファイル: GObject.cs プロジェクト: XIAOGUANCHANG/net-vips
        /// <summary>
        /// Connects a callback function (<paramref name="callback"/>) to a signal on this object.
        /// </summary>
        /// <remarks>
        /// The callback will be triggered every time this signal is issued on this instance.
        /// </remarks>
        /// <param name="detailedSignal">A string of the form "signal-name::detail".</param>
        /// <param name="callback">The callback to connect.</param>
        /// <param name="data">Data to pass to handler calls.</param>
        /// <returns>The handler id.</returns>
        /// <exception cref="T:System.Exception">If it failed to connect the signal.</exception>
        public uint SignalConnect(string detailedSignal, Delegate callback, IntPtr data = default)
        {
            // prevent the delegate from being re-located or disposed of by the garbage collector
            var delegateHandle = GCHandle.Alloc(callback);

            _handles.Add(delegateHandle);

            // get the pointer for the delegate which can be passed to the native code
            var callbackPtr = Marshal.GetFunctionPointerForDelegate(callback);
            var ret         = GSignal.ConnectData(this, detailedSignal, callbackPtr, data, null, default);

            if (ret == 0)
            {
                throw new Exception("Failed to connect signal.");
            }

            return(ret);
        }