Tipe tidak dapat disusun sebagai struktur yang tidak dikelola

Saya mencoba mengubah resolusi dalam proyek inti.

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

Pada baris ke-3 dari kode di atas, kode tersebut gagal dan menghasilkan kesalahan "tidak dapat disusun sebagai struktur yang tidak dikelola; tidak ada ukuran atau offset yang berarti yang dapat dihitung".

Adakah yang bisa memberikan wawasan tentang bagaimana saya harus memperbaikinya? Yang aneh adalah kode ini berfungsi dengan baik sebelum saya menarik beberapa kode lain yang seharusnya tidak mempengaruhi kode ini.

Struktur:

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

EDIT: Sekarang saya telah mengubah kode menjadi ini:

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

Namun saya mendapatkan kesalahan untuk dmpelsWidth, dmpelsHeight dan Dmsize. Anggota 'publik' harus didahulukan sebelum anggota 'pribadi'...

Ada ide?


person Mike    schedule 20.12.2018    source sumber
comment
Kita perlu melihat contoh minimal yang dapat direproduksi   -  person David Heffernan    schedule 20.12.2018
comment
@dymanoid Saya telah menambahkan kode struct, silakan melihatnya. :)   -  person Mike    schedule 20.12.2018
comment
@dymanoid Saya telah memperbarui kode yang saya gunakan beserta kesalahan yang saya dapatkan sekarang.   -  person Mike    schedule 20.12.2018
comment
Ini bukan kesalahan kompiler. Kesalahan ini berasal dari alat analisis kode statis atau dari alat seperti StyleCop. Pastikan Anda mengecualikan struct agar tidak diproses oleh alat tersebut.   -  person dymanoid    schedule 20.12.2018
comment
Terima kasih banyak @dymanoid, Anda telah mengajari saya banyak hal selama beberapa hari terakhir. Menggunakan pernyataan SuppressMessage yang memecahkan masalah saya.   -  person Mike    schedule 20.12.2018


Jawaban (1)


Bidang DmDeviceName tidak memiliki atribut MarshalAs.

Ini akan terlihat seperti:

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

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

Omong-omong, kode ini tidak ada gunanya:

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

Hapus saja garis-garis itu. Nilai-nilai tersebut akan diisi oleh fungsi WinAPI yang dipanggil (jika memungkinkan).

Dan masalah terbesarnya adalah: definisi struct Anda tidak valid! Urutan bidang itu penting! Anda tidak diperbolehkan untuk mengurutkan ulang kolom. Silakan gunakan definisi struct seperti yang saya posting di jawaban ini.

person dymanoid    schedule 20.12.2018
comment
Oh oke, itu yang aku buat saat itu! Terima kasih atas masukannya, sangat kami hargai. Saya harus memesan ulang bidang tersebut karena kesalahan yang seharusnya bersifat pribadi sebelum bidang yang dilindungi, dll. - person Mike; 20.12.2018
comment
Oke jadi saya telah mengubahnya kembali ke tata letak sebelumnya seperti yang Anda instruksikan... Namun sekarang saya mendapat masalah, bidang Publik harus ada sebelum Pribadi. Ingatlah bahwa saya memerlukan DmPelsWidth, DmPelsHeight dan Dmsize untuk publik/dilindungi. - person Mike; 20.12.2018
comment
Tidak, Anda tidak memerlukan bidang tersebut untuk dijadikan publik atau dilindungi. Anda dapat mengeksposnya dengan properti. Namun, untuk struktur seperti ini Anda sebaiknya membuat semua bidang menjadi publik. - person David Heffernan; 20.12.2018
comment
Saya menjadikannya pribadi & hanya dapat dibaca karena Bamboo memerlukannya agar berhasil membuatnya. Di sinilah saya mengalami masalah... - person Mike; 20.12.2018
comment
struct ini untuk P/Panggil. Anda harus mengecualikan struct ini dari analisis kode statis atau menambahkan penekanan aturan diagnostik untuk menghindari kesalahan build. - person dymanoid; 20.12.2018