Работа с неуправляемой памятью - указатель на указатель - C#

Узнай цену своей работы

Формулировка задачи:

Доброго всем времени суток! Пишу ПО для работы с PCI-express картой, в качестве драйвера - Jungo WinDriver. Необходимо выделить непрерывную оперативную память для работы по DMA. В Jungo для этого есть WDC_DMAContigBufLock (http://www.jungo.com/st/support/docu...00000000000000) Из всех параметров меня интересует ppDma (для записи адресов в регистры платы).
 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;
 
        }
При попытке вызвать Marshal.PtrToStructure(my_pointer, typeof(WD_DMA)) получаю
Необработанное исключение типа "System.AccessViolationException" в mscorlib.dll
Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
Если посмотреть дебаггером в память по полученному указателю (my_pointer), то там явно лежит что-то, отличное от нуля. ЧТЯДНТ?

Решение задачи: «Работа с неуправляемой памятью - указатель на указатель»

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

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.333 из 5
Похожие ответы