Тип нельзя маршалировать как неуправляемую структуру

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

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

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

        [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. «Общедоступные» члены должны предшествовать «частным» членам...

Любые идеи?


person Mike    schedule 20.12.2018    source источник
comment
Нам нужен минимальный воспроизводимый пример   -  person David Heffernan    schedule 20.12.2018
comment
@dymanoid Я добавил код структуры, не стесняйтесь взглянуть. :)   -  person Mike    schedule 20.12.2018
comment
@dymanoid Я обновил код, который я использую, вместе с ошибками, которые я сейчас получаю.   -  person Mike    schedule 20.12.2018
comment
Это не ошибки компилятора. Эти ошибки возникают из-за инструмента статического анализа кода или из такого инструмента, как StyleCop. Убедитесь, что вы исключили структуру из обработки этими инструментами.   -  person dymanoid    schedule 20.12.2018
comment
Большое спасибо, @dymanoid, вы многому меня научили за последние пару дней. Использовал оператор SuppressMessage, который решил мою проблему.   -  person Mike    schedule 20.12.2018


Ответы (1)


В поле 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 (когда это возможно).

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

person dymanoid    schedule 20.12.2018
comment
Ой, это я тогда накосячил! Спасибо за ваш вклад, очень признателен. Мне пришлось изменить порядок полей из-за ошибок, что частные должны быть перед защищенными полями и т. д. - person Mike; 20.12.2018
comment
Итак, я вернул его к предыдущему макету, как вы указали... Однако теперь у меня возникла проблема: общедоступные поля должны располагаться перед частными. Имейте в виду, что мне нужно, чтобы DmPelsWidth, DmPelsHeight и Dmsize были общедоступными/защищенными. - person Mike; 20.12.2018
comment
Нет, вам не нужно, чтобы эти поля были общедоступными или защищенными. Вы можете выставить их с помощью свойства. Однако для такой структуры вы также можете сделать все поля общедоступными. - person David Heffernan; 20.12.2018
comment
Я делаю их приватными и только для чтения, потому что Bamboo требует этого для успешной сборки. Вот у меня проблема... - person Mike; 20.12.2018
comment
Это struct для P/Invoke. Вы должны исключить эту структуру из статического анализа кода или добавить подавление диагностического правила, чтобы избежать ошибок сборки. - person dymanoid; 20.12.2018