Вы не можете определить динамический массив в большинстве систем на базе Codesys. Тем не менее, при необходимости можно создавать функции и блоки для обработки массивов динамического размера через VAR_IN_OUT ( TwinCAT 3 - см. Эту ссылку ).
ПРИМЕЧАНИЕ. На самом деле в новейших версиях TwinCAT 3 также можно выделить динамическую память с помощью команды __NEW
( см. Эту ссылку ). Я еще не проверял это, но есть пример, как создать размер байтового массива 25 во время выполнения. Это может быть отличным способом, но могут возникнуть некоторые проблемы, так как вам нужно удалить используемую память после того, как она больше не нужна, с помощью функции __DELETE
.
В этих системах распространено соглашение о создании массива настолько большого, насколько это когда-либо потребуется. Поэтому подумайте о теоретическом максимуме количества точек в файле и создайте массив такого размера. Тогда вам просто нужно знать, сколько очков вы добавили для последующего использования. Этот метод очень безопасен в использовании, поэтому я бы посоветовал вам начать с него вместо __NEW
.
Небольшой простой код, который поможет вам понять:
PROGRAM PRG_XmlTest
VAR CONSTANT
MAXIMUM_ARRAY_SIZE : UINT := 9999;
END_VAR
VAR
PointArray : ARRAY[0..MAXIMUM_ARRAY_SIZE] OF REAL;
PointsInArray : UINT;
i : UINT;
END_VAR
//Deleting old data before loading
MEMSET(
destAddr := ADR(PointArray),
fillByte := 0,
n := SIZEOF(PointArray)
);
PointsInArray := 0;
//Loading your XML. NOTE: This is not a working code
WHILE Xml.HasPoints() DO
IF PointsInArray < MAXIMUM_ARRAY_SIZE THEN
PointArray[PointsInArray] := XmlReader.GetPoint();
PointsInArray := PointsInArray + 1;
ELSE
//Overflow, array is full. Do something
EXIT;
END_IF
END_WHILE
//To do something with your data.
//NOTE: Using MIN to prevent faults if PointsInArray has too large value
FOR i := 0 TO MIN(PointsInArray, MAXIMUM_ARRAY_SIZE) DO
DoSomething(PointArray[i]);
END_FOR