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); } }