Skip to content

Commit 220755d

Browse files
shimatclaude
andcommitted
Add OpenCvSafeHandle.Null and migrate optional mask/control arguments to it
Every extern that already used a SafeHandle for its own "this" handle still fell back to a plain IntPtr (and a manual GC.KeepAlive) for optional arguments referencing another native object, since there was no way to express "no handle" through a SafeHandle-typed parameter. OpenCvSafeHandle.Null (a non-owning handle wrapping a null pointer) closes that gap. Migrated: LSDDetector.Detect(mask), FeaturesMatcher.Apply(mask), KalmanFilter.Predict(control), Mat/UMat.SetTo(mask), FileNode.ReadMat/ReadSparseMat(defaultValue). Each now passes `x?.Handle ?? OpenCvSafeHandle.Null` and drops the now-redundant GC.KeepAlive for that argument. Added KalmanTest.PredictWithoutControl/ PredictWithControl since Predict() previously had no test coverage. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 87c8d92 commit 220755d

14 files changed

Lines changed: 52 additions & 30 deletions

File tree

src/OpenCvSharp/Fundamentals/OpenCvSafeHandle.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,11 @@ protected OpenCvSafeHandle(IntPtr existingHandle, bool ownsHandle)
4444

4545
/// <inheritdoc />
4646
public override bool IsInvalid => handle == IntPtr.Zero;
47+
48+
/// <summary>
49+
/// A non-owning handle wrapping a null native pointer. Pass this for an optional
50+
/// SafeHandle-typed P/Invoke argument (e.g. a mask) when the caller has none, instead
51+
/// of overloading the parameter type with a plain <see cref="IntPtr"/>.
52+
/// </summary>
53+
public static OpenCvSafeHandle Null { get; } = new OpenCvPtrSafeHandle(IntPtr.Zero, ownsHandle: false, releaseAction: null);
4754
}

src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_line_descriptor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static partial ExceptionStatus line_descriptor_LSDDetector_new2(
2929

3030
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
3131
public static partial ExceptionStatus line_descriptor_LSDDetector_detect1(
32-
OpenCvSafeHandle obj, IntPtr image, IntPtr keypoints, int scale, int numOctaves, IntPtr mask);
32+
OpenCvSafeHandle obj, IntPtr image, IntPtr keypoints, int scale, int numOctaves, OpenCvSafeHandle mask);
3333

3434
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
3535
public static partial ExceptionStatus line_descriptor_LSDDetector_detect2(

src/OpenCvSharp/Internal/PInvoke/NativeMethods/core/NativeMethods_core_FileNode.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ public static partial ExceptionStatus core_FileNode_readRaw(
8080
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
8181
public static partial ExceptionStatus core_FileNode_read_String(OpenCvSafeHandle node, IntPtr value, [MarshalAs(UnmanagedType.LPStr)] string? defaultValue);
8282
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
83-
public static partial ExceptionStatus core_FileNode_read_Mat(OpenCvSafeHandle node, IntPtr mat, IntPtr defaultMat);
83+
public static partial ExceptionStatus core_FileNode_read_Mat(OpenCvSafeHandle node, IntPtr mat, OpenCvSafeHandle defaultMat);
8484
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
85-
public static partial ExceptionStatus core_FileNode_read_SparseMat(OpenCvSafeHandle node, IntPtr mat, IntPtr defaultMat);
85+
public static partial ExceptionStatus core_FileNode_read_SparseMat(OpenCvSafeHandle node, IntPtr mat, OpenCvSafeHandle defaultMat);
8686
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
8787
public static partial ExceptionStatus core_FileNode_read_vectorOfKeyPoint(OpenCvSafeHandle node, IntPtr keypoints);
8888
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]

src/OpenCvSharp/Internal/PInvoke/NativeMethods/core/NativeMethods_core_Mat.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ public static partial ExceptionStatus core_Mat_ones_MatShape(
107107
public static partial ExceptionStatus core_Mat_assignTo(OpenCvSafeHandle self, IntPtr m, int type);
108108

109109
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
110-
public static partial ExceptionStatus core_Mat_setTo_Scalar(OpenCvSafeHandle self, Scalar value, IntPtr mask);
110+
public static partial ExceptionStatus core_Mat_setTo_Scalar(OpenCvSafeHandle self, Scalar value, OpenCvSafeHandle mask);
111111
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
112-
internal static partial ExceptionStatus core_Mat_setTo_InputArray(OpenCvSafeHandle self, in InputArrayProxy value, IntPtr mask);
112+
internal static partial ExceptionStatus core_Mat_setTo_InputArray(OpenCvSafeHandle self, in InputArrayProxy value, OpenCvSafeHandle mask);
113113

114114
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
115115
public static partial ExceptionStatus core_Mat_reshape1(

src/OpenCvSharp/Internal/PInvoke/NativeMethods/core/NativeMethods_core_UMat.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ static partial class NativeMethods
8484
public static partial ExceptionStatus core_UMat_assignTo(OpenCvSafeHandle self, IntPtr m, int type);
8585

8686
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
87-
public static partial ExceptionStatus core_UMat_setTo_Scalar(OpenCvSafeHandle self, Scalar value, IntPtr mask);
87+
public static partial ExceptionStatus core_UMat_setTo_Scalar(OpenCvSafeHandle self, Scalar value, OpenCvSafeHandle mask);
8888
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
89-
internal static partial ExceptionStatus core_UMat_setTo_InputArray(OpenCvSafeHandle self, in InputArrayProxy value, IntPtr mask);
89+
internal static partial ExceptionStatus core_UMat_setTo_InputArray(OpenCvSafeHandle self, in InputArrayProxy value, OpenCvSafeHandle mask);
9090

9191
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
9292
public static partial ExceptionStatus core_UMat_reshape1(

src/OpenCvSharp/Internal/PInvoke/NativeMethods/stitching/NativeMethods_stitching_Matchers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static partial ExceptionStatus stitching_FeaturesMatcher_apply(
4545
public static partial ExceptionStatus stitching_FeaturesMatcher_apply2(
4646
OpenCvSafeHandle obj,
4747
WImageFeatures[] features, int featuresSize,
48-
IntPtr mask,
48+
OpenCvSafeHandle mask,
4949
IntPtr outSrcImgIdx,
5050
IntPtr outDstImgIdx,
5151
IntPtr outMatches,

src/OpenCvSharp/Internal/PInvoke/NativeMethods/video/NativeMethods_video_tracking.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public static partial ExceptionStatus video_KalmanFilter_init(OpenCvSafeHandle o
7979
public static partial ExceptionStatus video_KalmanFilter_delete(IntPtr obj);
8080

8181
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
82-
public static partial ExceptionStatus video_KalmanFilter_predict(OpenCvSafeHandle obj, IntPtr control, out IntPtr returnValue);
82+
public static partial ExceptionStatus video_KalmanFilter_predict(OpenCvSafeHandle obj, OpenCvSafeHandle control, out IntPtr returnValue);
8383

8484
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
8585
public static partial ExceptionStatus video_KalmanFilter_correct(OpenCvSafeHandle obj, IntPtr measurement, out IntPtr returnValue);

src/OpenCvSharp/Modules/core/FileNode.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,7 @@ public Mat ReadMat(Mat? defaultMat = null)
512512
try
513513
{
514514
NativeMethods.HandleException(
515-
NativeMethods.core_FileNode_read_Mat(Handle, value.CvPtr, Cv2.ToPtr(defaultMat)));
516-
GC.KeepAlive(defaultMat);
515+
NativeMethods.core_FileNode_read_Mat(Handle, value.CvPtr, defaultMat?.Handle ?? OpenCvSafeHandle.Null));
517516
}
518517
catch
519518
{
@@ -534,8 +533,7 @@ public SparseMat ReadSparseMat(SparseMat? defaultMat = null)
534533
try
535534
{
536535
NativeMethods.HandleException(
537-
NativeMethods.core_FileNode_read_SparseMat(Handle, value.CvPtr, Cv2.ToPtr(defaultMat)));
538-
GC.KeepAlive(defaultMat);
536+
NativeMethods.core_FileNode_read_SparseMat(Handle, value.CvPtr, defaultMat?.Handle ?? OpenCvSafeHandle.Null));
539537
}
540538
catch
541539
{

src/OpenCvSharp/Modules/core/Mat/Mat.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,11 +1350,9 @@ public Mat SetTo(Scalar value, Mat? mask = null)
13501350
{
13511351
ThrowIfDisposed();
13521352

1353-
var maskPtr = Cv2.ToPtr(mask);
13541353
NativeMethods.HandleException(
1355-
NativeMethods.core_Mat_setTo_Scalar(Handle, value, maskPtr));
1354+
NativeMethods.core_Mat_setTo_Scalar(Handle, value, mask?.Handle ?? OpenCvSafeHandle.Null));
13561355

1357-
GC.KeepAlive(mask);
13581356
return this;
13591357
}
13601358

@@ -1368,12 +1366,10 @@ public Mat SetTo(InputArray value, Mat? mask = null)
13681366
{
13691367
ThrowIfDisposed();
13701368

1371-
var maskPtr = Cv2.ToPtr(mask);
13721369
NativeMethods.HandleException(
1373-
NativeMethods.core_Mat_setTo_InputArray(Handle, value.Proxy, maskPtr));
1370+
NativeMethods.core_Mat_setTo_InputArray(Handle, value.Proxy, mask?.Handle ?? OpenCvSafeHandle.Null));
13741371

13751372
GC.KeepAlive(value.Source);
1376-
GC.KeepAlive(mask);
13771373
return this;
13781374
}
13791375

src/OpenCvSharp/Modules/core/Mat/UMat.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -769,11 +769,9 @@ public UMat SetTo(Scalar value, UMat? mask = null)
769769
{
770770
ThrowIfDisposed();
771771

772-
var maskPtr = Cv2.ToPtr(mask);
773772
NativeMethods.HandleException(
774-
NativeMethods.core_UMat_setTo_Scalar(Handle, value, maskPtr));
773+
NativeMethods.core_UMat_setTo_Scalar(Handle, value, mask?.Handle ?? OpenCvSafeHandle.Null));
775774

776-
GC.KeepAlive(mask);
777775
return this;
778776
}
779777

@@ -787,12 +785,10 @@ public UMat SetTo(InputArray value, UMat? mask = null)
787785
{
788786
ThrowIfDisposed();
789787

790-
var maskPtr = Cv2.ToPtr(mask);
791788
NativeMethods.HandleException(
792-
NativeMethods.core_UMat_setTo_InputArray(Handle, value.Proxy, maskPtr));
789+
NativeMethods.core_UMat_setTo_InputArray(Handle, value.Proxy, mask?.Handle ?? OpenCvSafeHandle.Null));
793790

794791
GC.KeepAlive(value.Source);
795-
GC.KeepAlive(mask);
796792
return this;
797793
}
798794

0 commit comments

Comments
 (0)