Работа с неуправляемой памятью - указатель на указатель - C#
Формулировка задачи:
Доброго всем времени суток!
Пишу ПО для работы с PCI-express картой, в качестве драйвера - Jungo WinDriver.
Необходимо выделить непрерывную оперативную память для работы по DMA.
В Jungo для этого есть WDC_DMAContigBufLock (http://www.jungo.com/st/support/docu...00000000000000)
Из всех параметров меня интересует ppDma (для записи адресов в регистры платы).
При попытке вызвать Marshal.PtrToStructure(my_pointer, typeof(WD_DMA)) получаю
Если посмотреть дебаггером в память по полученному указателю (my_pointer), то там явно лежит что-то, отличное от нуля.
ЧТЯДНТ?
public void AllocateDMABuffer() { IntPtr[] dma_buf = new IntPtr[2]; WD_DMA[] pDMA = new WD_DMA[2]; ulong[] physAddr = new ulong[2]; unsafe { for (uint i = 0; i < 2; ++i) { IntPtr my_pointer = Marshal.AllocHGlobal(Marshal.SizeOf(pDMA[i])); Marshal.StructureToPtr(pDMA[i], my_pointer, false); dwStatus = wdc_lib_decl.WDC_DMAContigBufLock(Handle, ref dma_buf[i], DMA_FROM_DEVICE, LVDS_PCI_DMA_BUFFER,ref my_pointer); pDMA[i] = (WD_DMA)Marshal.PtrToStructure(my_pointer, typeof(WD_DMA)); physAddr[i] = pDMA[i].Page[0].pPhysicalAddr; } } wdc_lib_decl.WDC_WriteAddr32(Handle, ioAddrSpace, LVDS_PCI_REG_ALSB, (uint)physAddr[0]); wdc_lib_decl.WDC_WriteAddr32(Handle, ioAddrSpace, LVDS_PCI_REG_AMSB, 0); return;// WD_ERROR_CODES.WD_STATUS_SUCCESS; }
Необработанное исключение типа "System.AccessViolationException" в mscorlib.dll Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
Решение задачи: «Работа с неуправляемой памятью - указатель на указатель»
textual
Листинг программы
IntPtr[] dma_buf = new IntPtr[2]; WD_DMA[] pDMA = new WD_DMA[2]; ulong[] physAddr = new ulong[2]; var marshaller = new MarshalWdDma(); // unsafe не нужен, у вас нет работы с указателями напрямую for ( uint i = 0; i < 2; ++i ) { // Выделять память для WD_DMA не нужно, судя по документации этим занимается функция IntPtr pDma = IntPtr.Zero; dwStatus = WDC_DMAContigBufLock( Handle, ref dma_buf[i], DMA_FROM_DEVICE, LVDS_PCI_DMA_BUFFER, ref pDma ); pDMA[i] = (WD_DMA)marshaller.MarshalNativeToManaged(pDma); physAddr[i] = pDMA[i].Page[0].pPhysicalAddr; }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д