Object Array to Byte Array - запрос фрагментации Marshal.AllocHGlobal - PullRequest
0 голосов
/ 14 июня 2011

Я не думаю, что было бы справедливо оставлять комментарий к ответу Fredrik Mörk в этом 2-летнем сообщении , поэтому я подумал, что просто задам его каквместо этого новый вопрос ...

NB: Это ни в коем случае не критический ответ , я просто пытаюсь все это понять, прежде чем углубляться в управление памятью / класс маршала.

В этом ответе функция GetByteArray выделяет память для каждого объекта в пределах данного массива в цикле.

Будет ли полезна функция GetByteArray в вышеупомянутом постевообще от выделения памяти для общего размера предоставленного массива:

Dim arrayBufferPtr = Marshal.AllocHGlobal(Marshal.SizeOf(<arrayElement>) * <array>.Count)

Мне просто интересно, вызывает ли выделение памяти, как показано в ответе, какую-либо фрагментацию?Предполагая, что может быть фрагментация, будет ли значительный эффект для беспокойства?Выделение памяти способом, который я показал, заставит вас вызывать IntPtr.ToInt ## для получения смещений указателя из общего указателя выделения и, следовательно, заставит вас проверить базовую архитектуру, чтобы убедиться, что используется правильный метод *1 или есть способ получше?(ToInt32 / ToInt64 в зависимости от x86 / 64?)

* 1 В другом месте я читал, что неправильный вызов IntPtr.ToInt ## вызовет исключения переполнения.Под этим утверждением я подразумеваю:

Dim anOffsetPtr As New IntPtr(arrayBufferPtr.ToInt## + (loopIndex * <arrayElementSize>))

Я прочитал несколько статей о классе VB.Net Marshal и распределении памяти;перечисленные ниже, но если вы знаете какие-либо другие хорошие статьи, я все уши!

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx

http://www.dotnetbips.com/articles/44bad06d-3662-41d3-b712-b45546cd8fa8.aspx

Мой любимый до сих пор: http://www.codeproject.com/KB/vb/Marshal.aspx

1 Ответ

2 голосов
/ 14 июня 2011

Можно выделить неуправляемую память для всего массива, а затем скопировать каждый элемент массива со значением SizeOf (arrayElement) * loopIndex.Лучше использовать соответствующий метод ToInt32 / ToInt64, в соответствии с текущей платформой, например:

Dim anOffsetPtr 
if arrayBufferPtr.Size = 4 then
    anOffsetPtr  = New IntPtr(arrayBufferPtr.ToInt32() + (loopIndex * arrayElementSize)) 
else
    anOffsetPtr  = New IntPtr(arrayBufferPtr.ToInt64() + (loopIndex * arrayElementSize)) 
endif
...