更改C#中的结构以匹配新的C定义

更改C#中的结构以匹配新的C定义,c#,wpf,struct,C#,Wpf,Struct,我正在开发一个使用C#+WPF分析嵌入式系统固件的程序。该固件是用C编写的,包含许多结构。其中一个结构在新固件版本后已更改。我的软件必须支持所有固件版本 固件版本1 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct MainStruct { public byte Member1; public byte Member2; [MarshalAs(UnmanagedType

我正在开发一个使用C#+WPF分析嵌入式系统固件的程序。该固件是用C编写的,包含许多结构。其中一个结构在新固件版本后已更改。我的软件必须支持所有固件版本

固件版本1

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MainStruct
{
    public byte Member1;
    public byte Member2;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
    public UInt16[] Member3;
}
固件版本2

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MainStruct
{
    public byte Member1;
    public Uint Member2;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public UInt16[] Member3;
}
逻辑

软件执行的步骤概述:

  • 接入设备
  • 获取固件版本
  • 选择结构

  • 如何确保兼容性?

    使结构的两个版本都实现一个接口。使您的接口具有每个对象的getter和setter。确保正确处理铸件

    interface MainStructInterface()
    {
        void setMember1(byte b);
        byte getMember1();
        void setMember2(Uint b); // Cast to byte in the first firmware version struct.
        Uint getMember2();
        // etc
    }
    
    此外,请查看此结构布局格式:

        [StructLayout(LayoutKind.Explicit, Pack = 1)]
        public unsafe struct StructMessage
        {
            [FieldOffset(0)] public fixed byte data[13]
            [FieldOffset(0)] public byte Member1;
            [FieldOffset(1)] public Uint Member2;
            [FieldOffset(5)] public fixed UInt16 Member3[4];
        }
    

    使用这种格式,您可以将所有内容加载到字节数组中,然后非常轻松地访问每个成员。

    您可以使用依赖项注入来实例化特定于固件的结构工厂吗?因此,如果您检测到固件A,您将创建结构版本1,但固件C将为您的答案创建结构版本2。我将考虑使用接口。我有一个关于您的结构布局的问题。我的结构布局有什么不同?在布局中,如何将字节数组转换为结构。谢谢。使用我的布局,您可以指定重叠的成员。因此,在我给出的示例中,名为“data”的字节数组与所有其他成员使用相同的空间。
        [StructLayout(LayoutKind.Explicit, Pack = 1)]
        public unsafe struct StructMessage
        {
            [FieldOffset(0)] public fixed byte data[13]
            [FieldOffset(0)] public byte Member1;
            [FieldOffset(1)] public Uint Member2;
            [FieldOffset(5)] public fixed UInt16 Member3[4];
        }