12

Greetings.

In C#: If I have an int[] array declared like this

int[] array = new array[size];

there is an way to get the IntPtr from this array?

The thing is that I'm using the EmguCV framework, and there is an constructor to create an image which takes an IntPtr to the pixel data, in order to build an image from an array (int[]).

Image<Gray,Int32> result = new Image<Gray,int>(bitmap.Width,bitmap.Height,stride,"**array.toPointer??**");

By the way if someone could told me how to calculate the stride, that would be great.

João Cardoso
  • 351
  • 3
  • 5
  • 13

2 Answers2

23

You should be able to do this without unsafe code using GCHandle. Here is a sample:

GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
    IntPtr pointer = handle.AddrOfPinnedObject();
}
finally
{
    if (handle.IsAllocated)
    {
        handle.Free();
    }
}
Bryan
  • 2,775
  • 3
  • 28
  • 40
  • Any way to go the other way around without copying data? – jjxtra Sep 03 '15 at 01:24
  • This isn't copying the data. It is telling the GC that you want a pointer to a managed object and don't move it on me (like when a collection happens). – Bryan Sep 03 '15 at 19:25
  • I mean is it possible to create a managed array without copying the unmanaged data – jjxtra Sep 04 '15 at 02:09
  • This is definitely how Microsoft does it. – Xcalibur37 Jan 30 '16 at 16:18
  • You don't need the `handle.IsAllocated` check, a pinned handle will remain allocated until `Free`d and if the constructor returned it will always have been allocated – SWdV Nov 21 '21 at 00:04
10

Use unsafe code, like this:

unsafe
{
  fixed (int* pArray = array)
  {
    IntPtr intPtr = new IntPtr((void *) pArray);
  }
}
Marcel Gheorghita
  • 1,853
  • 13
  • 19
  • 10
    And of course note that intPtr only points to the array *while control is in the fixed block*. Once you leave the fixed block the garbage collector is free to move pArray around in memory again and the intPtr could therefore be pointing to garbage. – Eric Lippert Feb 10 '10 at 17:36
  • Well, good thing this `intPtr` is only visible inside the fixed block. – Aleksei Petrenko Jul 31 '17 at 13:57
  • Often times you want to pass the pointer to some unmanaged code, where you are going to copy the memory anyway. In those cases this is the correct solution. – Giacomo d'Antonio Jan 05 '21 at 07:36