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.