Using arrays within a C# structure


So, I am moving from VB. Net and C++ to C#. One of the items that I’m used to using is a structure and typedef statements. One of the hurdles I encountered was declaring an array within a structure.

As an example, in C++, I would declare the following typedef:

typedef exmpl
{
   int a[100];
   short c[100];
   float f[100];
}

exmp e;

e.a[1] = 1;
e.c[1] = 2;
e.f[1] = 1.0;

The two questions I asked myself were:

  • How do I declare an array within a C# structure?
  • Once declared, how do I use the arrays and the structure?

After some researching, I came up with the answers.

To declare an array within a structure, one must use the StructLayout and MarshalAs attributes.

The MSDN discussion on StructLayout is found here.  A MSDN discussion on Marshalling is found here.

Now, the solution I used involves two steps.  First, the declaration of the arrays within in a structure.

[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct L1CMN
{

   [MarshalAs(UnmanagedType.U4, SizeConst=100)]public uint[] lngVal;
   [StructLayout(LayoutKind.Sequential, Pack=1)]
      [MarshalAs(UnmanagedType.U4, SizeConst=100)]public UInt16[] shtMask;
      [MarshalAs(UnmanagedType.R4, SizeConst = 100)] public float[] fltVal;
};

Just some side notes:

  • LayoutKind.Sequential is the default layout.  I specify it to make the code clearer.
  • Pack defines the alignment of the variables within the structure.  By using Pack=1, the alignment is on DWORD boundaries, which is 4 bytes.
  • The MarshalAs attribute seems to be the only way to define an array in a structure.  Even though the array is declared, memory is not yet allocated; this is done in the code itself.

Before we use these arrays, we must first allocate memory for the structure:

Then, we allocate memory for each array in the structure.  Now we can use the arrays as shown in this code snippet:


static L1CMN[] l1CmnRec = new L1CMN[50];

for (i = 0; i < 50; i++)
{
   l1CmnRec[i].lngVal = new uint[100];
   l1CmnRec[i].shtMask = new UInt16[100];
   l1CmnRec[i].fltVal = new float[100];
   int j;
   for (j = 0; j < 100; j++)
   {
       l1CmnRec[i].lngVal[j] = (uint)(i * j);
       l1CmnRec[i].shtMask[j] = (UInt16)(i * j);
       l1CmnRec[i].fltVal[j] = (float)(i * j);   
    }
}

Leave a comment