Im trying to read an alarm structure from a Beckhoff - PLC into a c# class. First i have to make the exact same structure in c# and it currently looks like this:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Alarm
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
public string text;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string objectName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public string[] instancePath = new string[6];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string timeStamp;
public int priority;
[MarshalAs(UnmanagedType.I1)]
public bool acknowledge;
[MarshalAs(UnmanagedType.I1)]
public bool disabled;
[MarshalAs(UnmanagedType.I1)]
public bool alarmIn;
}
Whats causing me problems is the "instancePath" field. When the field is a string i can use the "UnmanagedType.ByValTStr" attribute with SizeConst and when it's an array "UnmanagedType.ByValArray" but when i want to use a string[] i don't know what to do.
I've tried creating a new class:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class InstancePathDefinition
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string instancePath;
}
And used in my alarm class:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Alarm
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
public string text;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string objectName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public InstancePathDefinition[] instancePath = new InstancePathDefinition[6];
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 24)]
public string timeStamp;
public int priority;
[MarshalAs(UnmanagedType.I1)]
public bool acknowledge;
[MarshalAs(UnmanagedType.I1)]
public bool disabled;
[MarshalAs(UnmanagedType.I1)]
public bool alarmIn;
}
But when I use Marshal.SizeOf on my Alarm-class it gives me a size or 147 bytes instead of 189 bytes as I would expect.
EDIT: I think the reason for the difference in size is that only the array gets initiated and the class "InstancePathDefinition" doesn't.
I tried changing it from a class to a struct and now the sizes match.
I still find it strange though that I can't combine both UnmanagedType.ByValArray and UnmanagedType.ByValTStr as a sub type with different SizeConst.
Next I will need to create an array of the alarm class and that will get me into the same trouble again.