2013-06-12 5 views
0

Я выделяю IntPtr, указывающий на массив структуры, который будет использоваться с неуправляемым кодом. Я нашел много ресурсов на эту тему, и вот мой последний метод (кажется, работает хорошо):Как правильно освободить IntPtr, указывающий на неуправляемый массив?

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; 
} 

Теперь мои вопросы:

  • Как освободить правильно это привело указатель IntPtr? (Достаточно ли FreeHGlobal (указатель)?)
  • Есть ли какие-либо меры предосторожности, если я использую системную/прикладную платформу x86 или x64?

Те же вопросы для массива строк (полукокса ** в 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; 
} 

ответ

1

Да, вам нужно только позвонить Marshal.FreeHGlobal(hglobal), как только вы закончили использование памяти.

Поскольку вы используете IntPtr он будет автоматически работать на x86 или x64 платформ, потому что IntPtr заботится о разнице в размере указателя для вас.

Однако вы не должны использовать ToInt64() для выполнения арифметики указателей.

Вместо

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

ли это:

IntPtr ptr = IntPtr.Add(result, elemSize * i); 
+0

Thx. Как насчет массива строк? –

+0

Строковый массив использует память из 'AllocHGlobal()', которая вызывается из 'StringToHGlobalAnsi()', поэтому то же самое относится - просто вызывайте 'FreeHGlobal()' в IntPtr, возвращаемом из 'StringToHGlobalAnsi()', чтобы освободить память. Также не забудьте использовать 'IntPtr.Add()' для выполнения арифметики указателя для примера строки. –

+0

Вы имеете в виду, что мне просто нужно освободить strPtr, а не указатель результата с FreeHGlobal? –