0

I allocate IntPtr pointing to an array of struct to be used with unmanaged code. I found lot of resources on this subject and here is my final method (seems to work well):

public IntPtr ArrayToPtr<T>(T[] array)
{
    int size = array.Length;
    int elemSize = Marshal.SizeOf(typeof(T));

    IntPtr result = Marshal.AllocHGlobal(elemSize * size);

    for (int i = 0; i < size; i++)
    {
        IntPtr ptr = new IntPtr(result.ToInt64() + elemSize * i);
        Marshal.StructureToPtr(array[i], ptr, false);
    }

    return result;
}

Now my questions:

  • How to free properly this resulted IntPtr pointer ? (Is a FreeHGlobal(pointer) is enough ?)
  • Is there any precaution to take if I use x86 or x64 system/application platform ?

Same questions for an array of strings (a char** in C):

public IntPtr ArrayOfStringToPtr(string[] array)
{
    int size = array.Length;
    int elemSize = IntPtr.Size;

    IntPtr result = Marshal.AllocHGlobal(elemSize * size);

    for (int i = 0; i < size; i++)
    {
        IntPtr strPtr = Marshal.StringToHGlobalAnsi(array[i]);
        Marshal.StructureToPtr(strPtr, new IntPtr(result.ToInt64() + elemSize * i), false);
    }

    return result;
}
Eric David
  • 261
  • 3
  • 14

1 Answers1

1

Yes, you only need to call Marshal.FreeHGlobal(hglobal) once you have finished using the memory.

Because you are using IntPtr it will automatically work on x86 or x64 platforms because IntPtr takes care of the difference in pointer size for you.

However, you shouldn't use ToInt64() to do your pointer arithmetic.

Instead of

IntPtr ptr = new IntPtr(result.ToInt64() + elemSize * i);

Do this:

 IntPtr ptr = IntPtr.Add(result, elemSize * i);
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Thx. What about the string array ? – Eric David Jun 12 '13 at 08:49
  • The string array is using memory from `AllocHGlobal()` which is called from `StringToHGlobalAnsi()` so the same applies - just call `FreeHGlobal()` on the IntPtr returned from `StringToHGlobalAnsi()` to free the memory. Also remember to use `IntPtr.Add()` to do pointer arithmetic for the string example too. – Matthew Watson Jun 12 '13 at 09:10
  • Do you mean I just need to free the strPtr and not the result pointer with FreeHGlobal ? – Eric David Jun 12 '13 at 09:15
  • @EricDavid No I mean you have to free both using FreeHGlobal. – Matthew Watson Jun 12 '13 at 09:20