如何在c#中固定一个指向托管对象的指针

本文关键字:一个 指针 对象 | 更新日期: 2023-09-27 18:04:18

非托管代码调用我的函数。在第一个函数中,我应该传递回指针到我的托管对象。有时稍后,我的其他函数会被调用,使用同样的指针作为参数之一。我应该去引用它,用它来做一些计算,如果不需要的话,就把它处理掉。简而言之,我需要固定该对象,以便GC在我处理它之前不会移动它。如何在c#中做到这一点?

如何在c#中固定一个指向托管对象的指针

要在c#中固定一个对象,可以使用带有第二个参数GCHandleType.PinnedGCHandle.Alloc方法。对象保持固定,直到使用GCHandle.Free方法释放GCHandle实例。

(Circa 2022, Dotnet 6)

另一个答案不适用于托管对象。在运行时,它将失败。下面的代码将按照请求执行。

public static class Pin
{
    /// <summary>
    /// use to obtain raw access to a managed object.  allowing pinning.
    /// <para>
    /// Usage:<code>fixed (byte* data = [AND_OPERATOR]GetRawObjectData(managed)){  }</code>
    /// </para>
    /// </summary>
    public static ref byte GetRawObjectData(object o)
    {
        //usage:  fixed (byte* data = &GetRawObjectData(managed)) { }
        return ref new PinnableUnion(o).Pinnable.Data;
    }
    [StructLayout(LayoutKind.Sequential)]
    sealed class Pinnable
    {
        public byte Data;
    }
    [StructLayout(LayoutKind.Explicit)]
    struct PinnableUnion
    {
        [FieldOffset(0)]
        public object Object;
        [FieldOffset(0)]
        public Pinnable Pinnable;
        public PinnableUnion(object o)
        {
            System.Runtime.CompilerServices.Unsafe.SkipInit(out this);
            Object = o;
        }
    }
}