Skip to main content
Email Password   helpLost your password?

Introduction

This article describes a very short helper class to work with unmanaged memory that must be pinned to prevent the garbage collector from moving it. This is a particular requirement when working with the Win32 API's asynchronous I/O methods, which I found myself doing when implementing a USB device interface.

There is no download; simply copy the code from this article--please do not remove the copyright.

The Code

There really isn't much to this code:

Here's the code:

// (c) 2007 Marc Clifton

using System;
using System.Runtime.InteropServices;

namespace Clifton.Tools.Interop
{
  /// <summary>

  /// A helper class for pinning a managed structure so that it is suitable for

  /// unmanaged calls. A pinned object will not be collected and will not be moved

  /// by the GC until explicitly freed.

  /// </summary>

  public class PinnedObject<T> : IDisposable where T : struct
  {
    protected T managedObject;
    protected GCHandle handle;
    protected IntPtr ptr;
    protected bool disposed;

    public T ManangedObject
    {
      get 
      {
        return (T)handle.Target;
      }
      set
      {
        Marshal.StructureToPtr(value, ptr, false);
      }
    }

    public IntPtr Pointer
    {
      get { return ptr; }
    }

    public PinnedObject()
    {
      handle = GCHandle.Alloc(managedObject, GCHandleType.Pinned);
      ptr = handle.AddrOfPinnedObject();
    }

    ~PinnedObject()
    {
      Dispose();
    }

    public void Dispose()
    {
      if (!disposed)
      {
        handle.Free();
        ptr = IntPtr.Zero;
        disposed = true;
      }
    }
  }
}

Example

Using Unsafe Pointers In C#

This example illustrates manipulating a PinnedObject using C++ style pointer syntax within an unsafe code block. The code illustrates:

using System;

using Clifton.Tools.Interop;

namespace pintest
{
  public struct TestStruct
  {
    public int a;
  }

  public static class Test
  {
    public static void Main()
    {
      PinnedObject<TestStruct> pin = new PinnedObject<TestStruct>();
      TestStruct ts = new TestStruct();
      ts.a = 1;
      pin.ManangedObject = ts;

      unsafe
      {
        TestStruct* p = (TestStruct*)pin.Pointer;
        ++p->a;
      }

    Console.WriteLine(pin.ManangedObject.a);
    }
  }
}

Conclusion

A simple class but hopefully you will find it useful for the strong type management and functionality that it encapsulates.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralPinning copy of the structure Pin
Lesheniuk
6:04 2 Mar '07  
GeneralRe: Pinning copy of the structure Pin
Marc Clifton
6:18 2 Mar '07  
Questionfixed statement Pin
rvpilot
11:48 13 Feb '07  
AnswerRe: fixed statement Pin
Marc Clifton
12:06 13 Feb '07  
GeneralRe: fixed statement Pin
rvpilot
12:14 13 Feb '07  
GeneralTesting Pin
Luc Pattyn
13:07 12 Feb '07  
GeneralRe: Testing Pin
Marc Clifton
14:28 12 Feb '07  
GeneralMy .NET 1.1 approach, without generics Pin
Luc Pattyn
12:27 12 Feb '07  


Last Updated 11 Feb 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009