Wie kann der Ergebniswert bei verschachtelten String-Bausteinen vollständig abgebildet werden?
Falls Sie Bausteine mit STRING
-Werten ohne einer maximalen Länge (z.B. String-Bausteine) verschachtelt in der Anwendung verwenden, ist der zur Verfügung stehende Speicher dafür beschränkt. Diese Beschränkung ist abhängig vom verwendeten Zielsystem (siehe "Zielsystem-spezifische Eigenschaften und Einschränkungen"). In Folge ist es möglich, dass:
und
Falls Sie beide Folgen vermeiden wollen, verwenden Sie Bausteine mit STRING
-Werten ohne einer maximalen Länge nicht verschachtelt. Bei anwenderdefinierten Bausteinen können beide erwähnten Folgen nicht eintreten, da darin die STRING
-Variablen mit einer maximalen Länge deklariert werden müssen.
Auch falls Sie die Bausteine nicht verschachtelt verwenden, ist es natürlich trotzdem möglich, dass der STRING
-Ergebniswert nicht im zur Verfügung stehenden Speicher abgebildet werden kann. In diesem Fall wird übrigens der Ausgang ENO
des Bausteins auf den Wert FALSE
(oder eine Entsprechung) gesetzt (siehe auch Abschnitt "Interne Fehlerdiagnose für Baustein" in den Baustein-Beschreibungen, wie sich der Baustein verhält).
Die folgenden Beispiele mit dem CONCAT
-Baustein geben Ihnen ein Überblick über mögliche Verwendungen und deren Folgen. Der CONCAT
-Baustein wurde für die Beispiele ausgewählt, da er sowohl über Eingänge als auch über einen Ergebniswert vom Datentyp STRING
ohne einer maximalen Länge verfügt. Die berechneten Werte werden mit Hilfe des Assert
-Bausteins ausgewertet.
Beachten Sie: Je größer ein STRING
-Wert ist, desto mehr Arbeitsspeicher wird am Zielsystem benötigt. Falls kein ausreichender Arbeitsspeicher auf dem Zielsystem verfügbar ist, kann die Anwendung auf das Zielsystem wahrscheinlich gar nicht erfolgreich geladen werden.
Beispiel 1: CONCAT ohne Verschachtelung, ENO=TRUE
Der Ergebniswert wird vollständig abgebildet, da resultString1
mit einer Länge von 300 Zeichen deklariert ist. Das Verhalten auf unterschiedlichen Zielsystemen ist identisch, da CONCAT
nicht verschachtelt benutzt wird (die Beschränkung des Speichers wird hier nicht angewendet).
FUNCTION_BLOCK ConcatSample1
VAR
resultString1 : STRING[300];
length1 : INT;
eno1 : BOOL;
stringLength100 : STRING[100] := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
END_VAR
(* The 3 inputs amount to 300 characters. This is OK because 'resultString1' has a length of 300 characters. So 'eno1' evaluates to 'TRUE'. *)
resultString1 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>eno1);
length1 := LEN(resultString1);
ASSERT(length1=300);
ASSERT(eno1);
END_FUNCTION_BLOCK
|
Beispiel 2: CONCAT ohne Verschachtelung, ENO=FALSE (da Ergebniswert zu lang)
Der Ergebniswert wird nicht vollständig abgebildet, da resultString2
mit einer Länge von 200 Zeichen deklariert ist. Das Verhalten auf unterschiedlichen Zielsystemen ist aber identisch, da CONCAT
nicht verschachtelt benutzt wird (die Beschränkung des Speichers wird hier nicht angewendet).
FUNCTION_BLOCK ConcatSample2
VAR
resultString2 : STRING[200];
length2 : INT;
eno2 : BOOL;
stringLength100 : STRING[100] := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
END_VAR
(* The 3 inputs amount to 300 characters. But 'resultString2' has a length of 200 characters. So 'eno2' evaluates to 'FALSE'. *)
resultString2 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>eno2);
length2 := LEN(resultString2);
ASSERT(length2=200);
ASSERT(NOT eno2);
END_FUNCTION_BLOCK
|
Beispiel 3: CONCAT ohne Verschachtelung, ENO=TRUE – keine Beschränkung auf 1.024 Zeichen
Der Ergebniswert wird vollständig abgebildet, da resultString3
mit einer Länge von 1,500 Zeichen deklariert ist. Das Verhalten auf unterschiedlichen Zielsystemen ist identisch, da CONCAT
nicht verschachtelt benutzt wird. Auch hier wird die Beschränkung des Speichers nicht angewendet. Dies ist daran erkennbar, dass der Ergebniswert von 1.200 Zeichen vollständig abgebildet wird (eigentlich würde er die Grenze von 1.024 Bytes beim Laufzeitsystem für Windows überschreiten).
FUNCTION_BLOCK ConcatSample3
VAR
resultString3 : STRING[1500];
length3 : INT;
eno3 : BOOL;
stringLength100 : STRING[100] := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
END_VAR
(* The 11 inputs amount to 1100 characters. This is OK again because 'resultString3' has a length of 1500 characters. So 'eno3' evaluates to 'TRUE'. *)
resultString3 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, IN4 := stringLength100, IN5 := stringLength100, IN6 := stringLength100, IN7 := stringLength100, IN8 := stringLength100, IN9 := stringLength100, IN10 := stringLength100, IN11 := stringLength100, ENO=>eno3);
length3 := LEN(resultString3);
ASSERT(length3=1100);
ASSERT(eno3);
END_FUNCTION_BLOCK
|
Beispiel 4: CONCAT mit Verschachtelung, ENO einiger inneren CONCATs=FALSE – Beschränkung auf 1.024 Zeichen
Der zusammengesetzte Ergebniswert wird nicht vollständig abgebildet, obwohl resultString4
mit einer Länge von 1.500 Zeichen deklariert ist. Das Verhalten auf unterschiedlichen Zielsystemen ist nicht identisch, da CONCAT
verschachtelt benutzt wird. Somit wird hier die Beschränkung des Speichers angewendet – bei Laufzeitsystem für Windows ist dies 1.024 Bytes. Beachten Sie, dass 1 Byte vom Speicher pro CONCAT
-Aufruf für interne Zwecke verwendet wird. Falls eine andere Beschränkung für das Zielsystem gilt (z.B. für Controllinos), entsteht ein anderer Ergebniswert.
FUNCTION_BLOCK ConcatSample4
VAR
resultString4a : STRING[1500];
length4a : INT;
eno4a, enoA1, enoB1, enoC1, enoD1 : BOOL;
stringLength100 : STRING[100] := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
END_VAR
(* Here there is a nested usage of CONCAT. The scenario is as follows:
Unsized strings are assigned to 4 inputs of the outer CONCAT by calling CONCAT blocks again. Let's call them the inner CONCATs.
A string with a length of 100 characters is assigned to the 3 inputs of each inner CONCAT. For the runtime system for Windows, this is valid:
* The 3 inputs of the 1st inner CONCAT amount to 300 characters. 1 byte of the memory is used for internal purpose. As 301 < 1024, 'enoA1' evaluates to 'TRUE'. 300 characters can be mapped in the available memory.
* The 3 inputs of the 2nd inner CONCAT ampunt to 300 characters as well. 1 byte of the memory is again used for internal purpose. As 602 < 1024, 'enoB1' evaluates to 'TRUE'. 300 characters can be mapped in the available memory.
* The 3 inputs of the 3rd inner CONCAT amount to 300 characters as well. 1 byte of the memory is again used for internal purpose. As 903 < 1024, 'enoC1' evaluates to 'TRUE'. 300 characters can be mapped in the available memory.
* The 3 inputs of the 4th inner CONCAT amount to 300 characters as well. 1 byte of the memory is again used for internal purpose. As 1204 > 1024, 'enoD1' evaluates to 'FALSE'. Only 120 characters (of the 300 characters) can be mapped in the available memory.
So a string of 1020 characters is assigned to the outer CONCAT (300 + 300 + 300 + 120). This is OK because 'resultString4a' has a length of 1500 characters. So 'eno4a' evaluates to 'TRUE'. *)
resultString4a := CONCAT(IN1 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoA1), IN2 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoB1), IN3 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoC1), IN4 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoD1), ENO=>eno4a);
length4a := LEN(resultString4a);
ASSERT(length4a=1020); (* Valid for: runtime system for Windows. In case of a Controllino Maxi, 'resultString4a' would just have a length of 63 characters. *)
ASSERT(eno4a);
ASSERT(enoA1);
ASSERT(enoB1);
ASSERT(enoC1);
ASSERT(NOT enoD1);
END_FUNCTION_BLOCK
|
Beispiel 5: Analog zu Beispiel 4, aber ohne Verschachtelung und alle ENO=TRUE – keine Beschränkung auf 1.024 Zeichen
Der Ergebniswert wird vollständig abgebildet, da resultString5
mit einer Länge von 1,500 Zeichen deklariert ist. Das Verhalten auf unterschiedlichen Zielsystemen ist identisch, da CONCAT
nicht verschachtelt benutzt wird. Auch hier wird die Beschränkung des Speichers nicht angewendet. Dies ist daran erkennbar, dass der Ergebniswert von 1.200 Zeichen vollständig abgebildet wird (eigentlich würde er die Grenze von 1.024 Bytes beim Laufzeitsystem für Windows überschreiten).
FUNCTION_BLOCK ConcatSample5
VAR
resultString5 : STRING[1500];
length5 : INT;
eno5, enoV1, enoV2, enoV3, enoV4 : BOOL;
VarString1, VarString2, VarString3, VarString4 : STRING[300];
stringLength100 : STRING[100] := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
END_VAR
(* Here a workaround to avoid the restriction of 1024 bytes. Assign the result of the previously "inner" CONCAT blocks to STRING variables. Here all ENOs evaluate to 'TRUE'. *)
VarString1 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoV1);
VarString2 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoV2);
VarString3 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoV3);
VarString4 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoV4);
(* Then assign these STRING variables to the inputs of the previously "outer" CONCAT. This makes the code easier to read as well. *)
resultString5 := CONCAT(IN1 := VarString1, IN2 := VarString2, IN3 := VarString3, IN4 := VarString4, ENO=>eno5);
length5 := LEN(resultString5);
ASSERT(length5=1200);
ASSERT(eno5);
ASSERT(enoV1);
ASSERT(enoV2);
ASSERT(enoV3);
ASSERT(enoV4);
END_FUNCTION_BLOCK
|
Beispiel 6: Beispiel 4 um einen inneren CONCAT erweitert, ENO einiger inneren CONCATs=FALSE – Beschränkung auf 1.024 Zeichen
Der zusammengesetzte Ergebniswert wird wieder nicht vollständig abgebildet, obwohl resultString6
mit einer Länge von 1.500 Zeichen deklariert ist. Das Verhalten auf unterschiedlichen Zielsystemen ist nicht identisch, da CONCAT
verschachtelt benutzt wird. Somit wird hier die Beschränkung des Speichers angewendet – bei Laufzeitsystem für Windows ist dies 1.024 Bytes. Beachten Sie, dass 1 Byte vom Speicher pro CONCAT
-Aufruf für interne Zwecke verwendet wird. Falls eine andere Beschränkung für das Zielsystem gilt (z.B. für Controllinos), entsteht ein anderer Ergebniswert.
FUNCTION_BLOCK ConcatSample6
VAR
resultString6 : STRING[1500];
length6 : INT;
eno6, enoA2, enoB2, enoC2, enoD2, enoE2: BOOL;
stringLength100 : STRING[100] := '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789';
END_VAR
(* This is identical to example 4, but a 5th inner CONCAT is added. In addition to the behavior of example 4, the 300 characters of the 5th inner CONCAT cannot be mapped at all because there is no available memory left. So 'enoE2' evaluates to 'FALSE' (such as 'enoD2'). *)
resultString6 := CONCAT(IN1 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoA2), IN2 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoB2), IN3 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoC2), IN4 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoD2), IN5 := CONCAT(IN1 := stringLength100, IN2 := stringLength100, IN3 := stringLength100, ENO=>enoE2), ENO=>eno6);
length6 := LEN(resultString6);
ASSERT(length6=1020); (* Valid for: runtime system for Windows. In case of a Controllino Maxi Automation, 'resultString6' would just have a length of 63 characters. *)
ASSERT(eno6);
ASSERT(enoA2); (* Valid for: runtime system for Windows. In case of a Controllino Maxi Automation, 'enoA2' to 'enoD2' would evaluate to 'FALSE'. *)
ASSERT(enoB2);
ASSERT(enoC2);
ASSERT(NOT enoD2);
ASSERT(NOT enoE2);
END_FUNCTION_BLOCK
|