Unmanaged code calls my functions. In first function I should pass back pointer to my managed object. Sometimes later some of my other functions get called with that same pointer as one of parameters . I should dereference it and use it to perform some calculations and then if it is not needed dispose of it. To cut the story short I need to pin that object so that GC won't move it til I dispose of it. How to do that in C# ? Thanks in advance.
How to pin a pointer to managed object in C#?
Asked Answered
To pin an object in C#, you can use GCHandle.Alloc
method with second parameter GCHandleType.Pinned
. Object remains pinned until GCHandle
instance is released using GCHandle.Free
method.
It works like a charm when you use GCHandle.Aloc(object value) and cast it to IntPtr. –
Parsimonious
@apaka: GCHandle.Alloc(object_value, GCHandleType.Pinned) + GCHandle.AddrOfPinnedObject. –
Blanc
(Circa 2022, Dotnet 6)
The other answer doesn't work for managed objects. At runtime it will fail. Here is code that will do as requested.
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;
}
}
}
© 2022 - 2024 — McMap. All rights reserved.
List<>
. Now you can simply retrieve the managed reference in the callback from the handle value. – Aphid