Как прочитать массив различного размера из файла XML? - PullRequest
0 голосов
/ 13 ноября 2018

Я использую TwinCat, когда создаю программу для чтения моего XML-файла. Мне нужно прочитать массив точек в файле XML. но количество очков может варьироваться. Есть ли способ создать массив в зависимости от данных XML.

1 Ответ

0 голосов
/ 14 ноября 2018

Вы не можете определить динамический массив в большинстве систем на базе 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
...