Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT
Eine VAR_IN_OUT-Variable ist eine Ein- und Ausgabevariable, die Teil einer Bausteinschnittstelle ist und als formaler Durchgangsparameter dient.
Die VAR_IN_OUT-Variablen eines Bausteins müssen bei dem Aufruf des Bausteins zugewiesen werden.
Syntax:
<keyword> <POU name>
VAR_IN_OUT
<variable name> : <data type> ( := <initialization value> )? ;
END_VAR
<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG
Sie können eine Ein- und Ausgabevariable in den Programmierbausteinen PRG, FUNCTION_BLOCK, METHOD oder FUNCTION im Deklarationsabschnitt VAR_IN_OUT deklarieren. Als Initialisierungswert kann optional eine Konstante des deklarierten Datentyps zugewiesen werden. Die VAR_IN_OUT-Variable kann gelesen und beschrieben werden.
Verwendung:
- Aufruf: Bei Aufruf des Programmierbausteins erhält die formale VAR_IN_OUT-Variable als Argument die tatsächliche Variable, die so genannte „Durchgangsvariable“. Zur Laufzeit bei der Parameterübergabe wird dann keine Kopie erzeugt, sondern die formale Variable erhält eine Referenz auf die von außen übergebene tatsächliche Variable. Die referenziellen Variablen enthalten intern als Wert eine Speicheradresse auf den eigentlichen Wert (Übergabe als Pointer, Call-by-Reference). Es ist nicht möglich, als Argument direkt eine Konstante (Literal), eine konstante Variable oder eine Bitvariable anzugeben.
- Schreib-/Lesezugriff innerhalb des Programmierbausteins: Wenn innerhalb des Programmierbausteins auf die Variable geschrieben wird, wirkt dies auf die übergebene Variable durch. Wenn der Programmierbaustein verlassen wird, bleiben vorgenommene Änderungen somit erhalten. Das bedeutet, dass ein Programmierbaustein seine VAR_IN_OUT-Variablen so verwendet, wie der aufrufende Programmierbaustein seine Variablen verwendet. Ein Lesezugriff ist immer erlaubt.
- Schreib-/Lesezugriff von außen: VAR_IN_OUT-Variablen können nicht via <function block instance name>.<variable name> direkt von außen gelesen oder beschrieben werden. Dies funktioniert nur bei VAR_INPUT- und VAR_OUTPUT-Variablen.
- Übergabe von Stringvariablen: Wenn als Argument eine Stringvariable übergeben wird, sollten die tatsächliche Variable und die formale Variable die gleiche Länge haben. Andernfalls kann der übergebene String unbeabsichtigt manipuliert werden. Bei VAR_OUTPUT CONSTANT-Parametern tritt dieses Problem nicht auf.
- Übergabe von Bitvariablen: Eine Bitvariable kann nicht direkt an eine VAR_IN_OUT-Variable übergeben werden, sondern benötigt eine Zwischenvariable.
- Übergabe von Properties: Ist nicht erlaubt.
Übergabe von Zeichenketten an VAR_IN_OUT CONSTANT Wenn eine Zeichenkette als Variable oder auch als Konstante an eine formale VAR_IN_OUT CONSTANT-Variable übergeben wird, kann die Stringlänge variabel sein. Es wird aber maximal die Stringlänge der VAR_IN_OUT CONSTANT-Variablen verarbeitet. Weitere Informationen hierzu erhalten Sie unten auf dieser Seite. |
Übergabe von Eigenschaften nicht möglich An eine VAR_IN_OUT- oder eine VAR_IN_OUT CONSTANT-Variable kann keine Eigenschaft (Property) übergeben werden. Ausnahme: Eine Zuweisung auf VAR_IN_OUT (CONSTANT) ist möglich, falls die Eigenschaft den Rückgabetyp REFERENCE besitzt. Zu beachten ist hierbei allerdings, dass die Eigenschaft per REFERENCE nur eine Adresse zurückliefern darf, die über den Eigenschaftenaufruf hinaus gültig ist. Dies wäre z.B. nicht der Fall, wenn die Eigenschaft die Referenz auf eine temporäre Variable zurückliefern würde. |
Beispiel:
Funktionsbaustein FB_Sample
FUNCTION_BLOCK FB_Sample
VAR_IN_OUT
bInOut : BOOL;
END_VAR
Programm MAIN:
VAR
bTest : BOOL;
fbSample : FB_Sample;
END_VAR
fbSample(bInOut := bTest); // OK
fbSample(); // NOK: not possible as the VAR_IN_OUT variable is not assigned in this FB call
fbSample.bInOut := bTest; // NOK: direct access to VAR_IN_OUT variable from the outside not possible
Beispiel für einen Workaround für das Zuweisen einer Bitvariablen auf einen VAR_IN_OUT-Eingang:
Deklaration der Bitvariablen (bBit0):
VAR_GLOBAL
bBit0 AT %MX0.1 : BOOL;
bTemp : BOOL;
END_VAR
Funktionsbaustein mit VAR_IN_OUT Eingang bInOut:
FUNCTION_BLOCK FB_Test
VAR_INPUT
bIn : BOOL;
END_VAR
VAR_IN_OUT
bInOut : BOOL;
END_VAR
IF bIn THEN
bInOut := TRUE;
END_IF
Programm, das den Funktionsbaustein aufruft. Direktes Zuweisen der Bitvariablen auf den VAR_IN_OUT Eingang (Fehler) und Zuweisen mithilfe einer Zwischenvariablen (Workaround):
PROGRAM MAIN
VAR
bIn : BOOL;
fbTest1 : FB_Test;
fbTest2 : FB_Test;
END_VAR
// Error C0201: Type 'BIT' doesn't correspond to the type 'BOOL' of VAR_IN_OUT 'bInOut'
fbTest1(bIn := bIn, bInOut := bBit0);
// Workaround
//bTemp := bBit0;
//fbTest2(bIn := bIn, bInOut := bTemp);
//bBit0 := bTemp;
Übergabevariable VAR_IN_OUT CONSTANT
Eine VAR_IN_OUT CONSTANT-Variable dient als konstanter Durchgangsparameter, der gelesen, aber nicht beschrieben werden kann.
Syntax:
<keyword> <POU name>
VAR_IN_OUT CONSTANT
<variable name> : <data type>; // formal parameter
END_VAR
<keyword> : FUNCTION | FUNCTION_BLOCK | METHOD | PRG
VAR_IN_OUT CONSTANT-Variablen werden deklariert, ohne einen Initialisierungswert zuzuweisen.
Verwendung:
- Es sind alle Datentypen erlaubt.
- Schreibzugriffe auf die VAR_IN_OUT CONSTANT-Variable sind nicht erlaubt.
- Die Übergabe von Properties ist nicht erlaubt.
- Wenn die VAR_IN_OUT CONSTANT-Variable vom Typ STRING/WSTRING ist, kann bei Aufruf des Programmierbausteins eine Variable, eine konstante Variable oder eine Konstante (Literal) übergeben werden. Die Stringlänge der übergebenen Variablen/Konstanten kann beliebig sein und hängt nicht von der Stringlänge der VAR_IN_OUT CONSTANT-Variablen ab. Beachten Sie, dass maximal die Stringlänge der VAR_IN_OUT CONSTANT-Variablen verarbeitet wird.
- Wenn die VAR_IN_OUT CONSTANT-Variable nicht vom Typ STRING/WSTRING ist, kann bei Aufruf des Programmierbausteins eine Variable übergeben werden. Wenn die Compileroption Konstanten ersetzen in der Kategorie Übersetzen in den SPS-Projekteigenschaften deaktiviert ist, kann außerdem eine konstante Variable übergeben werden.
Wenn die Compileroption Konstanten ersetzen in der Kategorie Übersetzen in den SPS-Projekteigenschaften aktiviert ist, dann erzeugt die Parameterübergabe einer Konstanten mit Basisdatentyp ungleich STRING oder einer konstanten Variablen mit Basisdatentyp ungleich STRING einen Compilerfehler. |
Beispiel:
Im Code werden Strings über verschiedene VAR_IN_OUT-Variablen an die Funktion F_Manipulate übergeben. Bei Übergabe eines Literals an eine VAR_IN_OUT-Variable wird ein Compilerfehler ausgegeben. Bei Übergabe eines Literals an eine VAR_IN_OUT CONSTANT-Variable wird korrekter Code erzeugt, ebenso bei der Übergabe von Stringvariablen.
Des Weiteren ist zu erkennen, dass die Übergabe einer zu kurzen STRING-Variablen an eine VAR_IN_OUT-Variable nicht möglich ist (Compiler-Fehler), bei der Übergabe an eine VAR_IN_OUT CONSTANT-Variable ist dies hingegen möglich.
Funktion F_Manipulate:
FUNCTION F_Manipulate : BOOL
VAR_IN_OUT
sReadWrite : STRING(16); (* Can be read or written here in POU *)
nReadWrite : DWORD; (* Can be read or written here in POU *)
END_VAR
VAR_IN_OUT CONSTANT
cReadOnly : STRING(16); (* Constant string variable can only be read here in POU *)
END_VAR
sReadWrite := 'String_from_POU';
nReadWrite := STRING_TO_DWORD(cReadOnly);
Programm MAIN:
PROGRAM MAIN
VAR
sVar10 : STRING(10) := '1234567890';
sVar16 : STRING(16) := '1234567890123456';
sVar20 : STRING(20) := '12345678901234567890';
nVar : DWORD;
END_VAR
// The following line of code causes the compiler error:
// VAR_IN_OUT parameter 'sReadWrite' of 'F_Manipulate' needs variable with write access as input.
F_Manipulate(sReadWrite := '1234567890123456', cReadOnly := '1234567890123456', nReadWrite := nVar);
// The following line of code causes the compiler error:
// String variable 'sVar10' too short for VAR_IN_OUT parameter 'sReadWrite' of 'F_Manipulate'
F_Manipulate(sReadWrite := sVar10, cReadOnly := sVar10, nReadWrite := nVar);
// Correct code
F_Manipulate(sReadWrite := sVar16, cReadOnly := '1234567890', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := '1234567890123456', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := '12345678901234567890', nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := sVar10, nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar16, cReadOnly := sVar16, nReadWrite := nVar);
F_Manipulate(sReadWrite := sVar20, cReadOnly := sVar20, nReadWrite := nVar);