C# 类型不能作为非托管结构封送

C# 类型不能作为非托管结构封送,c#,winapi,struct,pinvoke,marshalling,C#,Winapi,Struct,Pinvoke,Marshalling,我正试图改变一个核心项目的解决方案 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行,它失败并产生“无法作为非托管结构封送;无法计算有意义的大小或偏移量”错误 有人能提供一些

我正试图改变一个核心项目的解决方案

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的错误“公共”成员必须排在“私人”成员之前


有什么想法吗?

DmDeviceName字段缺少
marshallas
属性

它应该是这样的:

[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函数填充(如果可能)


最大的问题是:您的结构定义无效!字段顺序非常重要!不允许您对字段重新排序。请像我一样使用结构定义。

我们需要查看@dymanoid。我已经添加了结构代码,请随意查看。:)@dymanoid我已经更新了我正在使用的代码以及我现在得到的错误。这些不是编译器错误。这些错误源于静态代码分析工具或类似StyleCop的工具。请确保您将结构排除在这些工具的处理之外。非常感谢@dymanoid,您在过去几天里教会了我很多。使用了SuppressMessage语句解决了我的问题。哦,好吧,这就是我当时搞砸的!谢谢你的意见,非常感谢。我不得不对字段重新排序,因为在保护字段之前应该有private等错误。好的,我已经按照您的指示将其更改回以前的布局。。。然而,现在我遇到了一个问题,“公共领域必须优先于私人领域”。请记住,我需要将DmPelsWidth、DmPelsHeight和Dmsize设置为公共/受保护。不,您不需要将这些字段设置为公共或受保护。您可以使用属性公开它们。然而,对于这样一个结构,你也可以将所有的领域公开。我将它们私有化&只读,因为竹子需要这样才能成功地建造它。这就是我遇到的问题…这个
struct
用于P/Invoke。您应该从静态代码分析中排除此结构,或者添加诊断规则抑制以避免生成错误。