如何修复警告 CA1900:成员 "X" 包含以下不可移植字段
How to fix Warning CA1900: Member "X" contains the following non-portable fields
我的 DevMode
结构的字段 Position
和 FormName
标有 CA1900
代码分析警告。
这似乎是一个危险的结构,在定义中稍作更改会产生很多问题并停止按预期工作(请参阅上面这些网址中的用户评论),所以我不知道具体如何调整上述字段以在 32 位和 64 位 Windows.
中按预期工作
如何使那些标记的字段可移植?
DevMode 结构(只是对 pinvoke.net 中发布的 C# 代码进行少量改编的翻译):
<DebuggerStepThrough>
<StructLayout(LayoutKind.Explicit)>
Public Structure DevMode
Public Const CchDeviceName As Integer = 32
Public Const CchFormName As Integer = 32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchDeviceName)>
<FieldOffset(0)>
Public DeviceName As String
<FieldOffset(32)>
Public SpecVersion As Short
<FieldOffset(34)>
Public DriverVersion As Short
<FieldOffset(36)>
Public Size As Short
<FieldOffset(38)>
Public DriverExtra As Short
<FieldOffset(40)>
Public Fields As DeviceModeFields
<FieldOffset(44)>
Public Orientation As Short
<FieldOffset(46)>
Public PaperSize As Short
<FieldOffset(48)>
Public PaperLength As Short
<FieldOffset(50)>
Public PaperWidth As Short
<FieldOffset(52)>
Public Scale As Short
<FieldOffset(54)>
Public Copies As Short
<FieldOffset(56)>
Public DefaultSource As Short
<FieldOffset(58)>
Public PrintQuality As Short
<FieldOffset(44)>
Public Position As Win32.Types.Point
<FieldOffset(52)>
Public DisplayOrientation As DeviceModeDisplayOrientation
<FieldOffset(56)>
Public DisplayFixedOutput As Integer
<FieldOffset(60)>
Public Color As Short
<FieldOffset(62)>
Public Duplex As Short
<FieldOffset(64)>
Public YResolution As Short
<FieldOffset(66)>
Public TTOption As Short
<FieldOffset(68)>
Public Collate As Short
<FieldOffset(72)>
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchFormName)>
Public FormName As String
<FieldOffset(102)>
Public LogPixels As Short
<FieldOffset(104)>
Public BitsPerPixel As Integer
<FieldOffset(108)>
Public PixelsWidth As Integer
<FieldOffset(112)>
Public PixelsHeight As Integer
<FieldOffset(116)>
Public DisplayFlags As Integer
<FieldOffset(116)>
Public Nup As Integer
<FieldOffset(120)>
Public DisplayFrequency As Integer
End Structure
点结构:
<DebuggerStepThrough>
<StructLayout(LayoutKind.Sequential)>
Public Structure Point
Public X As Integer
Public Y As Integer
Public Sub New(ByVal x As Integer, ByVal y As Integer)
Me.X = x
Me.Y = y
End Sub
Public Sub New(ByVal pt As System.Drawing.Point)
Me.New(pt.X, pt.Y)
End Sub
Public Shared Widening Operator CType(ByVal pt As Point) As System.Drawing.Point
Return New System.Drawing.Point(pt.X, pt.Y)
End Operator
Public Shared Widening Operator CType(ByVal pt As System.Drawing.Point) As Point
Return New Point(pt.X, pt.Y)
End Operator
End Structure
更新
这是原来的成员声明:
这是我按照@David Heffernan 的建议尝试过的方法,但是我做错了一些事情,因为当我在某些 winApi 函数中测试它时,该结构不再起作用。
我做错了什么?。如何最终解决这个问题?
<StructLayout(LayoutKind.Sequential)>
Public Structure DevMode
Private Const CchDeviceName As Integer = 32
Private Const CchFormName As Integer = 32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchDeviceName)>
Public DeviceName As String
Public SpecVersion As Short
Public DriverVersion As Short
Public Size As Short
Public DriverExtra As Short
Public Fields As DeviceModeFields
Public test1 As UnionDevMode1
Public test2 As UnionDevMode2
Public Color As Short
Public Duplex As Short
Public YResolution As Short
Public TTOption As Short
Public Collate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchFormName)>
Public FormName As String
Public LogPixels As Short
Public BitsPerPixel As Integer
Public PixelsWidth As Integer
Public PixelsHeight As Integer
Public test3 As UnionDevMode3
Public DisplayFrequency As Integer
Public IcmMethod As Integer
Public IcmIntent As Integer
Public MediaType As Integer
Public DitherType As Integer
Public Reserved1 As Integer
Public Reserved2 As Integer
Public PanningWidth As Integer
Public PanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode1
<FieldOffset(0)> Public Orientation As Short
<FieldOffset(0)> Public PaperSize As Short
<FieldOffset(0)> Public PaperLength As Short
<FieldOffset(0)> Public PaperWidth As Short
<FieldOffset(0)> Public Scale As Short
<FieldOffset(0)> Public Copies As Short
<FieldOffset(0)> Public DefaultSource As Short
<FieldOffset(0)> Public PrintQuality As Short
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode2
<FieldOffset(0)> Public Position As Win32.Types.Point
<FieldOffset(0)> Public DisplayOrientation As DeviceModeDisplayOrientation
<FieldOffset(0)> Public DisplayFixedOutput As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode3
<FieldOffset(0)> Public DisplayFlags As Integer
<FieldOffset(0)> Public Nup As Integer
End Structure
更新2
只是我尝试过的其他方式没有成功...
<StructLayout(LayoutKind.Sequential)>
Public Structure DevMode
Private Const CchDeviceName As Integer = 32
Private Const CchFormName As Integer = 32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchDeviceName)>
Public DeviceName As String
Public SpecVersion As Short
Public DriverVersion As Short
Public Size As Short
Public DriverExtra As Short
Public Fields As DeviceModeFields
Public test1 As UnionDevMode1
Public Color As Short
Public Duplex As Short
Public YResolution As Short
Public TTOption As Short
Public Collate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchFormName)>
Public FormName As String
Public LogPixels As Short
Public BitsPerPixel As Integer
Public PixelsWidth As Integer
Public PixelsHeight As Integer
Public test3 As UnionDevMode3
Public DisplayFrequency As Integer
Public IcmMethod As Integer
Public IcmIntent As Integer
Public MediaType As Integer
Public DitherType As Integer
Public Reserved1 As Integer
Public Reserved2 As Integer
Public PanningWidth As Integer
Public PanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode1
<FieldOffset(0)>
Public subUnion1 As SubUnionDevMode1
<FieldOffset(0)>
Public subUnion2 As SubUnionDevMode2
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure SubUnionDevMode1
Public Orientation As Short
Public PaperSize As Short
Public PaperLength As Short
Public PaperWidth As Short
Public Scale As Short
Public Copies As Short
Public DefaultSource As Short
Public PrintQuality As Short
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure SubUnionDevMode2
Public Position As Win32.Types.Point
Public DisplayOrientation As DeviceModeDisplayOrientation
Public DisplayFixedOutput As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode3
<FieldOffset(0)> Public DisplayFlags As Integer
<FieldOffset(0)> Public Nup As Integer
End Structure
终于解决了,感谢@David Heffernan 和公司的帮助...
我发现(幸运的是)让我疯狂地让结构工作的一件事是,如果 CharSet
属性设置为 Auto
然后结构停止工作,因为无论什么原因。
在使用 DEVMODE 结构的函数中,也应设置 Ansi 字符集(如 EnumDisplaySettings
、ChangeDisplaySettingsEx
等),否则该结构在我的情况下将不起作用,不仅仅是得到错误的字符,我的意思是其他字段也会出错。
下面是工作代码,或者至少它似乎按预期工作。所有偏移量都是等效的,结构的大小与原始大小一样为 156,至少在我的 Windows.
中是这样
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
Public Structure DevMode
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)>
Public DeviceName As String
Public SpecVersion As Short
Public DriverVersion As Short
Public Size As Short
Public DriverExtra As Short
Public Fields As Integer
Public Mode As DeviceMode
Public Color As Short
Public Duplex As Short
Public YResolution As Short
Public TTOption As Short
Public Collate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)>
Public FormName As String
Public LogPixels As Short
Public BitsPerPixel As Integer
Public PixelsWidth As Integer
Public PixelsHeight As Integer
Public Flags As DeviceFlags
Public DisplayFrequency As Integer
Public IcmMethod As Integer
Public IcmIntent As Integer
Public MediaType As Integer
Public DitherType As Integer
Public Reserved1 As Integer
Public Reserved2 As Integer
Public PanningWidth As Integer
Public PanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure DeviceMode
<FieldOffset(0)> Public PrinterDevMode As PrinterDevMode
<FieldOffset(0)> Public DisplayDevMode As DisplayDevMode
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure DeviceFlags
<FieldOffset(0)> Public DisplayFlags As Integer
<FieldOffset(0)> Public Nup As Integer
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure PrinterDevMode
Public Orientation As Short
Public PaperSize As Short
Public PaperLength As Short
Public PaperWidth As Short
Public Scale As Short
Public Copies As Short
Public DefaultSource As Short
Public PrintQuality As Short
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure DisplayDevMode
Public Position As Win32.Types.Point ' 8 bytes.
Public DisplayOrientation As Integer
Public DisplayFixedOutput As Integer
End Structure
我的 DevMode
结构的字段 Position
和 FormName
标有 CA1900
代码分析警告。
这似乎是一个危险的结构,在定义中稍作更改会产生很多问题并停止按预期工作(请参阅上面这些网址中的用户评论),所以我不知道具体如何调整上述字段以在 32 位和 64 位 Windows.
中按预期工作如何使那些标记的字段可移植?
DevMode 结构(只是对 pinvoke.net 中发布的 C# 代码进行少量改编的翻译):
<DebuggerStepThrough>
<StructLayout(LayoutKind.Explicit)>
Public Structure DevMode
Public Const CchDeviceName As Integer = 32
Public Const CchFormName As Integer = 32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchDeviceName)>
<FieldOffset(0)>
Public DeviceName As String
<FieldOffset(32)>
Public SpecVersion As Short
<FieldOffset(34)>
Public DriverVersion As Short
<FieldOffset(36)>
Public Size As Short
<FieldOffset(38)>
Public DriverExtra As Short
<FieldOffset(40)>
Public Fields As DeviceModeFields
<FieldOffset(44)>
Public Orientation As Short
<FieldOffset(46)>
Public PaperSize As Short
<FieldOffset(48)>
Public PaperLength As Short
<FieldOffset(50)>
Public PaperWidth As Short
<FieldOffset(52)>
Public Scale As Short
<FieldOffset(54)>
Public Copies As Short
<FieldOffset(56)>
Public DefaultSource As Short
<FieldOffset(58)>
Public PrintQuality As Short
<FieldOffset(44)>
Public Position As Win32.Types.Point
<FieldOffset(52)>
Public DisplayOrientation As DeviceModeDisplayOrientation
<FieldOffset(56)>
Public DisplayFixedOutput As Integer
<FieldOffset(60)>
Public Color As Short
<FieldOffset(62)>
Public Duplex As Short
<FieldOffset(64)>
Public YResolution As Short
<FieldOffset(66)>
Public TTOption As Short
<FieldOffset(68)>
Public Collate As Short
<FieldOffset(72)>
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchFormName)>
Public FormName As String
<FieldOffset(102)>
Public LogPixels As Short
<FieldOffset(104)>
Public BitsPerPixel As Integer
<FieldOffset(108)>
Public PixelsWidth As Integer
<FieldOffset(112)>
Public PixelsHeight As Integer
<FieldOffset(116)>
Public DisplayFlags As Integer
<FieldOffset(116)>
Public Nup As Integer
<FieldOffset(120)>
Public DisplayFrequency As Integer
End Structure
点结构:
<DebuggerStepThrough>
<StructLayout(LayoutKind.Sequential)>
Public Structure Point
Public X As Integer
Public Y As Integer
Public Sub New(ByVal x As Integer, ByVal y As Integer)
Me.X = x
Me.Y = y
End Sub
Public Sub New(ByVal pt As System.Drawing.Point)
Me.New(pt.X, pt.Y)
End Sub
Public Shared Widening Operator CType(ByVal pt As Point) As System.Drawing.Point
Return New System.Drawing.Point(pt.X, pt.Y)
End Operator
Public Shared Widening Operator CType(ByVal pt As System.Drawing.Point) As Point
Return New Point(pt.X, pt.Y)
End Operator
End Structure
更新
这是原来的成员声明:
这是我按照@David Heffernan 的建议尝试过的方法,但是我做错了一些事情,因为当我在某些 winApi 函数中测试它时,该结构不再起作用。
我做错了什么?。如何最终解决这个问题?
<StructLayout(LayoutKind.Sequential)>
Public Structure DevMode
Private Const CchDeviceName As Integer = 32
Private Const CchFormName As Integer = 32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchDeviceName)>
Public DeviceName As String
Public SpecVersion As Short
Public DriverVersion As Short
Public Size As Short
Public DriverExtra As Short
Public Fields As DeviceModeFields
Public test1 As UnionDevMode1
Public test2 As UnionDevMode2
Public Color As Short
Public Duplex As Short
Public YResolution As Short
Public TTOption As Short
Public Collate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchFormName)>
Public FormName As String
Public LogPixels As Short
Public BitsPerPixel As Integer
Public PixelsWidth As Integer
Public PixelsHeight As Integer
Public test3 As UnionDevMode3
Public DisplayFrequency As Integer
Public IcmMethod As Integer
Public IcmIntent As Integer
Public MediaType As Integer
Public DitherType As Integer
Public Reserved1 As Integer
Public Reserved2 As Integer
Public PanningWidth As Integer
Public PanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode1
<FieldOffset(0)> Public Orientation As Short
<FieldOffset(0)> Public PaperSize As Short
<FieldOffset(0)> Public PaperLength As Short
<FieldOffset(0)> Public PaperWidth As Short
<FieldOffset(0)> Public Scale As Short
<FieldOffset(0)> Public Copies As Short
<FieldOffset(0)> Public DefaultSource As Short
<FieldOffset(0)> Public PrintQuality As Short
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode2
<FieldOffset(0)> Public Position As Win32.Types.Point
<FieldOffset(0)> Public DisplayOrientation As DeviceModeDisplayOrientation
<FieldOffset(0)> Public DisplayFixedOutput As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode3
<FieldOffset(0)> Public DisplayFlags As Integer
<FieldOffset(0)> Public Nup As Integer
End Structure
更新2
只是我尝试过的其他方式没有成功...
<StructLayout(LayoutKind.Sequential)>
Public Structure DevMode
Private Const CchDeviceName As Integer = 32
Private Const CchFormName As Integer = 32
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchDeviceName)>
Public DeviceName As String
Public SpecVersion As Short
Public DriverVersion As Short
Public Size As Short
Public DriverExtra As Short
Public Fields As DeviceModeFields
Public test1 As UnionDevMode1
Public Color As Short
Public Duplex As Short
Public YResolution As Short
Public TTOption As Short
Public Collate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=CchFormName)>
Public FormName As String
Public LogPixels As Short
Public BitsPerPixel As Integer
Public PixelsWidth As Integer
Public PixelsHeight As Integer
Public test3 As UnionDevMode3
Public DisplayFrequency As Integer
Public IcmMethod As Integer
Public IcmIntent As Integer
Public MediaType As Integer
Public DitherType As Integer
Public Reserved1 As Integer
Public Reserved2 As Integer
Public PanningWidth As Integer
Public PanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode1
<FieldOffset(0)>
Public subUnion1 As SubUnionDevMode1
<FieldOffset(0)>
Public subUnion2 As SubUnionDevMode2
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure SubUnionDevMode1
Public Orientation As Short
Public PaperSize As Short
Public PaperLength As Short
Public PaperWidth As Short
Public Scale As Short
Public Copies As Short
Public DefaultSource As Short
Public PrintQuality As Short
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure SubUnionDevMode2
Public Position As Win32.Types.Point
Public DisplayOrientation As DeviceModeDisplayOrientation
Public DisplayFixedOutput As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure UnionDevMode3
<FieldOffset(0)> Public DisplayFlags As Integer
<FieldOffset(0)> Public Nup As Integer
End Structure
终于解决了,感谢@David Heffernan 和公司的帮助...
我发现(幸运的是)让我疯狂地让结构工作的一件事是,如果 CharSet
属性设置为 Auto
然后结构停止工作,因为无论什么原因。
在使用 DEVMODE 结构的函数中,也应设置 Ansi 字符集(如 EnumDisplaySettings
、ChangeDisplaySettingsEx
等),否则该结构在我的情况下将不起作用,不仅仅是得到错误的字符,我的意思是其他字段也会出错。
下面是工作代码,或者至少它似乎按预期工作。所有偏移量都是等效的,结构的大小与原始大小一样为 156,至少在我的 Windows.
中是这样<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
Public Structure DevMode
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)>
Public DeviceName As String
Public SpecVersion As Short
Public DriverVersion As Short
Public Size As Short
Public DriverExtra As Short
Public Fields As Integer
Public Mode As DeviceMode
Public Color As Short
Public Duplex As Short
Public YResolution As Short
Public TTOption As Short
Public Collate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)>
Public FormName As String
Public LogPixels As Short
Public BitsPerPixel As Integer
Public PixelsWidth As Integer
Public PixelsHeight As Integer
Public Flags As DeviceFlags
Public DisplayFrequency As Integer
Public IcmMethod As Integer
Public IcmIntent As Integer
Public MediaType As Integer
Public DitherType As Integer
Public Reserved1 As Integer
Public Reserved2 As Integer
Public PanningWidth As Integer
Public PanningHeight As Integer
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure DeviceMode
<FieldOffset(0)> Public PrinterDevMode As PrinterDevMode
<FieldOffset(0)> Public DisplayDevMode As DisplayDevMode
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure DeviceFlags
<FieldOffset(0)> Public DisplayFlags As Integer
<FieldOffset(0)> Public Nup As Integer
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure PrinterDevMode
Public Orientation As Short
Public PaperSize As Short
Public PaperLength As Short
Public PaperWidth As Short
Public Scale As Short
Public Copies As Short
Public DefaultSource As Short
Public PrintQuality As Short
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure DisplayDevMode
Public Position As Win32.Types.Point ' 8 bytes.
Public DisplayOrientation As Integer
Public DisplayFixedOutput As Integer
End Structure