Pangi Min
Pangi Min

Reputation: 69

Change struct in C# to match new C definition

I'm developing a program using C# + WPF for analyzing a firmware of a embedded system. This firmware is written in C and includes many structs. One of these structs has been changed following new firmware version. My software has to support all firmware versions.

Firmware ver.1

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

Firmware Ver.2

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

Logic

public void ShowStruct(MainStruct MyStruct)
{
    ShowData(MyStruct.Member3);
}

Outline of steps the software performs:

  1. Access device
  2. Get firmware version
  3. Select Struct

How to ensure compatibility?

Upvotes: 1

Views: 135

Answers (1)

Snowman Tackler
Snowman Tackler

Reputation: 29

Make both versions of your struct implement an interface. Make your interface have the getters and setters for each object. Make sure you handle casting correctly.

interface MainStructInterface()
{
    void setMember1(byte b);
    byte getMember1();
    void setMember2(Uint b); // Cast to byte in the first firmware version struct.
    Uint getMember2();
    // etc
}

Also, check out this struct layout formatting:

    [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];
    }

Using that format you can load everything into the byte array and then access each member very easily.

Upvotes: 2

Related Questions