Я пытаюсь прочитать структуру тревоги из ПЛК Beckhoff в класс c #.
Сначала я должен создать точно такую же структуру в c #, и сейчас она выглядит так:
[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;
}
Что вызывает у меня проблемы, это поле "instancePath".
Когда поле является строкой, я могу использовать атрибут «UnmanagedType.ByValTStr» с SizeConst, а когда это массив «UnmanagedType.ByValArray», но когда я хочу использовать строку [], я не знаю, что делать.
Я пытался создать новый класс:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class InstancePathDefinition
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string instancePath;
}
И используется в моем классе сигнализации:
[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;
}
Но когда я использую Marshal.SizeOf в моем классе Alarm, он дает мне размер или 147 байтов вместо 189 байтов, как я и ожидал.
EDIT:
Я думаю, что причина разницы в размере заключается в том, что инициализируется только массив, а класс InstancePathDefinition - нет.
Я попытался изменить его с класса на структуру, и теперь размеры совпадают.
Мне все еще кажется странным, что я не могу объединить UnmanagedType.ByValArray и UnmanagedType.ByValTStr как подтип с другим SizeConst.
Далее мне нужно будет создать массив класса тревоги, и это снова вызовет у меня ту же проблему.