Тип нельзя маршалировать как неуправляемую структуру - PullRequest
0 голосов
/ 20 декабря 2018

Я пытаюсь изменить разрешение в основном проекте.

var devmode = default(Devmode);
devmode.DmDeviceName = new string(new char[32]);
devmode.DmFormName = new string(new char[32]);
devmode.Dmsize = (short)Marshal.SizeOf(devmode);

В 3-й строке приведенного выше кода происходит сбой, и возникает ошибка «не может быть маршалирована как неуправляемая структура; невозможно вычислить значимый размер или смещение».

МожетКто-нибудь дать некоторое представление о том, как я должен исправить это?Странно то, что до того, как я вытащил какой-то другой код, который не должен был повлиять на этот код, он работал нормально.

Структура:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Devmode
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string DmFormName;
    public string DmDeviceName;

    public short Dmsize;

    public int DmPelsWidth;
    public int DmPelsHeight;

    private readonly short dmlogPixels;
    private readonly short dmbitsPerPel;
    private readonly int dmdisplayFlags;
    private readonly int dmdisplayFrequency;
    private readonly int dmiCMMethod;
    private readonly int dmiCMIntent;
    private readonly int dmmediaType;
    private readonly int dmditherType;
    private readonly int dmreserved1;
    private readonly int dmreserved2;
    private readonly int dmpanningWidth;
    private readonly int dmpanningHeight;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    private readonly short dmspecVersion;
    private readonly short dmdriverVersion;
    private readonly short dmdriverExtra;
    private readonly int dmfields;
    private readonly int dmpositionX;
    private readonly int dmpositionY;
    private readonly int dmdisplayOrientation;
    private readonly int dmdisplayFixedOutput;
    private readonly short dmcolor;
    private readonly short dmduplex;
    private readonly short dmyResolution;
    private readonly short dmtTOption;
    private readonly short dmcollate;
}

РЕДАКТИРОВАТЬ: теперь я изменил код наthis:

        [StructLayout(LayoutKind.Sequential)]
    public struct Devmode
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]

        private readonly string dmdeviceName;

        private readonly short dmspecVersion;
        private readonly short dmdriverVersion;

        public short Dmsize;

        private readonly short dmdriverExtra;
        private readonly int dmfields;
        private readonly int dmpositionX;
        private readonly int dmpositionY;
        private readonly int dmdisplayOrientation;
        private readonly int dmdisplayFixedOutput;
        private readonly short dmcolor;
        private readonly short dmduplex;
        private readonly short dmyResolution;
        private readonly short dmtTOption;
        private readonly short dmcollate;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
        private readonly string dmformName;
        private readonly short dmlogPixels;
        private readonly short dmbitsPerPel;

        public int dmpelsWidth;
        public int dmpelsHeight;

        private readonly int dmdisplayFlags;
        private readonly int dmdisplayFrequency;
        private readonly int dmiCMMethod;
        private readonly int dmiCMIntent;
        private readonly int dmmediaType;
        private readonly int dmditherType;
        private readonly int dmreserved1;
        private readonly int dmreserved2;
        private readonly int dmpanningWidth;
        private readonly int dmpanningHeight;
    }

Однако я получаю сообщение об ошибке для dmpelsWidth, dmpelsHeight и Dmsize.«Публичные» участники должны предшествовать «частным» членам ...

Есть идеи?

1 Ответ

0 голосов
/ 20 декабря 2018

В поле DmDeviceName отсутствует атрибут MarshalAs.

Он должен выглядеть следующим образом:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DmFormName;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DmDeviceName;

Кстати, этот код не имеет смысла:

devmode.DmDeviceName = new string(new char[32]);
devmode.DmFormName = new string(new char[32]);

Просто удали эти строки.Значения будут заполнены вызванной функцией WinAPI (когда это возможно).

И самая большая проблема: неверное определение структуры !Порядок полей важно !Вы не можете изменить порядок полей .Пожалуйста, используйте определение структуры, как я опубликовал в этом ответе .

...