Сбой при вызове ResetDC с devmode, скопированным в байтовый массив из маршаллированной структуры - PullRequest
0 голосов
/ 24 февраля 2011

Я получаю исключение System.AccessViolationException при вызове ResetDC при передаче моего Devmode. Я делаю следующее ..

// create and marshall the devmode to a byte array.

DEVMODE myDevmode = new DEVMODE {dmSize = (short) Marshal.SizeOf(typeof (DEVMODE))};

myDevmode.dmFields = DM.Orientation;
myDevmode.dmOrientation = DMORIENT_LANDSCAPE;

IntPtr ptDM = Marshal.AllocHGlobal(myDevmode.dmSize);
Marshal.StructureToPtr(myDevmode, ptDM, false);

byte[] byteDM = new byte[myDevmode.dmSize];
Marshal.Copy(ptDM, byteDM, 0, myDevmode.dmSize);

Затем я вызываю через интерфейс com (существующая архитектура изменить невозможно):

SetDevMode(ref byteDM[0], myDevmode.dmSize)

на другой стороне интерфейса com и обратно в коде .net с другой стороны выполняется следующее:

    public void SetDevMode(ref byte pDevMode, int nDevModeSize)
    {
        _pageSetupDevMode = new byte[nDevModeSize];

        unsafe
        {
            fixed (byte* p = &pDevMode)
            {
                Marshal.Copy((IntPtr)p, _pageSetupDevMode, 0, nDevModeSize);
            }
        }
    }

и на более поздний момент делается вызов ResetDC:

Win32.ResetDC(_hRefDc, ref _pageSetupDevMode[0]);

В этот момент я получаю исключение.

Произошло необработанное исключение типа 'System.AccessViolationException' Дополнительная информация: Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена.

Это происходит в gdi32.dll

Есть идеи?

1 Ответ

1 голос
/ 24 февраля 2011

Как упомянуто в комментарии выше, это была не проблема с обработкой памяти, а скорее результат передачи практически пустого devmode в ResetDC - я видел, как это было сделано в примере онлайн, но, похоже, он расстроил gdi во время печати.

Сейчас я получаю действительный devmode от принтера в качестве основы для приведенного выше кода, и это работает нормально. Извинения.

...