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。您应该从静态代码分析中排除此结构,或者添加诊断规则抑制以避免生成错误。