C# – How to put an array inside a struct in C#

c++code-translationpointers

C++ code:

struct tPacket
{
    WORD word1;
    WORD word2;
    BYTE byte1;
    BYTE byte2;
    BYTE array123[8];
}

static char data[8192] = {0};
...
some code to fill up the array
...
tPacket * packet = (tPacket *)data;

We can't do that as easy in C#.

Please note there is an array in the C++ structure.

Alternatively, using this source file could do the job for us, but not if there is an array in the structure.

Best Solution

I'm unsure of exactly what you are asking. Are you trying to get an equivalent structure definition in C# for plain old C# usage or for interop (PInvoke) purposes? If it's for PInvoke the follownig structure will work

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct tPacket {

    /// WORD->unsigned short
    public ushort word1;

    /// WORD->unsigned short
    public ushort word2;

    /// BYTE->unsigned char
    public byte byte1;

    /// BYTE->unsigned char
    public byte byte2;

    /// BYTE[8]
    [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=8, ArraySubType=System.Runtime.InteropServices.UnmanagedType.I1)]
    public byte[] array123;
}

If you are looking for a plain old C# structure that has the same characteristics, it's unfortunately not possible to do with a struct. You cannot define an inline array of a contstant size in a C# structure nor can you force the array to be a specific size through an initializer.

There are two alternative options in the managed world.

Use a struct which has a create method that fills out the array

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct tPacket {
    public ushort word1;
    public ushort word2;
    public byte byte1;
    public byte byte2;
    public byte[] array123;
    public static tPacket Create() { 
      return new tPacket() { array123 = new byte[8] };
    }
}

Or alternatively use a class where you can initialize the array123 member variable directly.

EDIT OP watns to know how to convert a byte[] into a tPacket value

Unfortunately there is no great way to do this in C#. C++ was awesome for this kind of task because has a very weak type system in that you could choose to view a stream of bytes as a particular structure (evil pointer casting).

This may be possible in C# unsafe code but I do not believe it is.

Essentially what you will have to do is manually parse out the bytes and assign them to the various values in the struct. Or write a native method which does the C style casting and PInvoke into that function.