ไม่สามารถรวมประเภทเป็นโครงสร้างที่ไม่มีการจัดการได้

ฉันกำลังพยายามเปลี่ยนความละเอียดในโครงการหลัก

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 ฉันได้เพิ่มโค้ด struct แล้ว ลองดูได้เลย :)   -  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/วิงวอน คุณควรแยกโครงสร้างนี้ออกจากการวิเคราะห์โค้ดแบบคงที่หรือเพิ่มการระงับกฎการวินิจฉัยเพื่อหลีกเลี่ยงข้อผิดพลาดในการสร้าง - person dymanoid; 20.12.2018