Позвольте мне начать с того, что я просмотрел и нашел описания использования fixed {}, Marshal.AllocHGlobal () и GCHandle.Alloc () на этом форуме и во многих ссылках в сети. Однако мне еще предстоит найти краткое объяснение того, когда использовать класс Marshal vs. класс GCHandle (с фиксированным {} и без него).
Я использую стороннюю библиотеку .NET, которая имеет метод под названием Readline () в классе «Buffer». В руководстве показан следующий прототип функции:
bool ReadLine (int x1, int y1, int x2, int y2, System.IntPtr bufData, out int numRead);
с описанием bufData, в котором говорится: ... Область памяти должна иметь количество байтов, большее или равное длине строки, умноженной на значение, возвращаемое функцией свойство BytesPerPixel.
Теперь позже в руководстве пользователя они действительно приводят пример доступа к буферу (который я немного изменил для моего конкретного примера):
// Create an array large enough to hold one line from buffer
int size = 640;
byte[] dataLine = new byte[size * 2]; // 2 bytes per pixel
// Pin the array to avoid Garbage collector moving it
GCHandle dataLineHandle = GCHandle.Alloc(dataLine, GCHandleType.Pinned);
IntPtr dataLineAddress = dataLineHandle.AddrOfPinnedObject();
и я мог бы следовать приведенный выше "пример" кода с:
// Read one line of buffer data
success = buffer.ReadLine(0, 0, 639, 0, dataLineAddress, out numRead);
// Unpin the array
dataLineHandle.Free()
Это может быть конец истории (и я еще не тестировал приведенный выше код), но я закончил поиском в Google класса GCHandle, который побудил меня пойти по пути взаимодействия с .NET, pInvoke и т. д.
Итак, мои вопросы ... 1) Почему я не могу использовать:
IntPtr dataLineAddress = Marshal.AllocHGlobal( size * 2 );
и передать его в ReadLine ()?
2) Могу ли я также использовать следующий фрагмент кода (извлеченный и измененный из примеров в Интернете):
int size = 640;
byte[] dataLine= new byte[size * 2]; // 2 bytes per pixel
// prevent garbage collector from moving buffer around in memory
fixed (byte* fixedDataLine = dataLine)
{
// get IntPtr representing address of first buffer element
IntPtr dataLineAddress= Marshal.UnsafeAddrOfPinnedArrayElement(fixedDataLine , 0);
success = buffer.ReadLine(0, 0, 639, 0, dataLineAddress, out numRead);
}
I ' Я буду интересоваться, кто может пролить свет на вышеуказанные методы и указать на мои ошибки в реализации, а также указать, когда вышеуказанные методы подходят. Наконец, даже если все вышеперечисленные методы действительны, есть ли в последние несколько лет общий толчок к тому или иному подходу?
Заранее спасибо !! Hyped