using System; using CeresSharp.Native; namespace CeresSharp.Native.SafeHandles; /// /// Safe handle for Ceres CostFunction. /// internal sealed class CostFunctionHandle : BaseSafeHandle { private volatile bool _ownedByProblem = false; private CostFunctionHandle() : base() { } private CostFunctionHandle(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle) { } public static CostFunctionHandle Create(IntPtr handle) { if (handle == IntPtr.Zero) { throw new Exceptions.CeresException(Exceptions.CeresErrorCode.NullPointer, "Cost function handle is null"); } return new CostFunctionHandle(handle, true); } /// /// Marks this cost function as owned by a Problem. /// When owned by Problem, the native handle should NOT be freed here /// because Problem/Ceres will free it when Problem is destroyed. /// internal void MarkOwnedByProblem() => _ownedByProblem = true; protected override void ReleaseNativeHandle(IntPtr handle) { if (_ownedByProblem) { // Problem owns this cost function - Ceres will delete it when Problem is freed. // Do NOT free here to avoid double-free. return; } // Standalone cost function - we must free it ourselves CeresNative.ceres_wrapper_free_autodiff_cost_function(handle); } }