Работа с неуправляемой памятью - указатель на указатель - 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;
}