Files
2023-03-12 20:34:16 +00:00

103 lines
2.3 KiB
C#

// Copyright (c) 2021 homuler
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
using System;
using System.Runtime.InteropServices;
namespace Mediapipe
{
public abstract class MpResourceHandle : DisposableObject, IMpResourceHandle
{
private IntPtr _ptr = IntPtr.Zero;
protected IntPtr ptr
{
get => _ptr;
set
{
if (value != IntPtr.Zero && OwnsResource())
{
throw new InvalidOperationException($"This object owns another resource");
}
_ptr = value;
}
}
protected MpResourceHandle(bool isOwner = true) : this(IntPtr.Zero, isOwner) { }
protected MpResourceHandle(IntPtr ptr, bool isOwner = true) : base(isOwner)
{
this.ptr = ptr;
}
#region IMpResourceHandle
public IntPtr mpPtr
{
get
{
ThrowIfDisposed();
return ptr;
}
}
public void ReleaseMpResource()
{
if (OwnsResource())
{
DeleteMpPtr();
}
ReleaseMpPtr();
TransferOwnership();
}
public bool OwnsResource()
{
return isOwner && IsResourcePresent();
}
#endregion
protected override void DisposeUnmanaged()
{
if (OwnsResource())
{
DeleteMpPtr();
}
ReleaseMpPtr();
base.DisposeUnmanaged();
}
/// <summary>
/// Forgets the pointer address.
/// After calling this method, <see ref="OwnsResource" /> will return false.
/// </summary>
protected void ReleaseMpPtr()
{
ptr = IntPtr.Zero;
}
/// <summary>
/// Release the memory (call `delete` or `delete[]`) whether or not it owns it.
/// </summary>
/// <remarks>In most cases, this method should not be called directly</remarks>
protected abstract void DeleteMpPtr();
protected delegate MpReturnCode StringOutFunc(IntPtr ptr, out IntPtr strPtr);
protected string MarshalStringFromNative(StringOutFunc f)
{
f(mpPtr, out var strPtr).Assert();
GC.KeepAlive(this);
var str = Marshal.PtrToStringAnsi(strPtr);
UnsafeNativeMethods.delete_array__PKc(strPtr);
return str;
}
protected bool IsResourcePresent()
{
return ptr != IntPtr.Zero;
}
}
}