Datentyp: ANY, ANY_<Typ>
Die Datentypen ANY oder ANY_<Typ> werden in Schnittstellen von Funktionen, Funktionsbausteinen oder Methoden verwendet, um Eingangsparameter, deren Typ unbekannt oder beliebig ist, formal zu typisieren: Die Eingangsvariablen (VAR_INPUT) haben einen generischen Datentyp.
Der Compiler ersetzt den Typ der Eingangsvariable intern mit der unten beschriebenen Datenstruktur, wobei der Wert nicht direkt übergeben wird. Stattdessen wird ein Zeiger auf den eigentlichen Wert übergeben, weswegen nur eine Variablen übergeben werden kann. Erst beim Aufruf wird also der Datentyp konkretisiert. Aufrufe solcher Programmierbausteine können daher mit Argumenten, die jeweils unterschiedliche Datentypen haben, erfolgen.
Tipp
Literale, ersetzte Konstanten und Ergebnisse von Funktionsaufrufen oder Ausdrücken können nicht an Eingangsvariablen (VAR_IN_OUT) übergeben werden.
Interne Datenstruktur bei ANY und ANY_<Typ>
Beim Übersetzen des Codes werden die Eingangsvariablen mit ANY-Datentyp intern durch die folgende Struktur typisiert. Bei Aufruf des Programmierbausteins (zur Laufzeit) wird das Argument an einen Referenzparameter übergeben.
TYPE AnyType :
STRUCT
// Type of the current parameter
typeclass : __SYSTEM.TYPE_CLASS ;
// Pointer to the current parameter
pvalue : POINTER TO BYTE;
// Size of the data to which the pointer points
diSize : DINT;
END_STRUCT
END_TYPETipp
Über diese Struktur können Sie innerhalb des Programmierbausteins auf die Eingangsvariable zugreifen und beispielsweise den übergebenen Wert abfragen.
Die Funktion vergleicht, ob zwei Eingangsvariablen den gleichen Typ und den gleichen Wert haben.
FUNCTION funGenericCompare : BOOL
// Declaration
VAR_INPUT
any1 : ANY;
any2 : ANY;
END_VAR
VAR
pTest : POINTER TO ARRAY [0..100] OF POINTER TO DWORD;
diCount: DINT;
END_VAR
// Implementation
pTest := ADR(any1);
Generic_Compare := FALSE;
IF any1.typeclass <> any2.typeclass THEN
RETURN;
END_IF
IF any1.diSize <> any2.diSize THEN
RETURN;
END_IF
// Byte comparison
FOR iCount := 0 TO any1.diSize-1 DO
IF any1.pvalue[iCount] <> any2.pvalue[iCount] THEN
RETURN;
END_IF
END_FOR
Generic_Compare := TRUE;
RETURN;
Deklaration
Die Syntaxbeschreibungen beziehen sich auf einen Programmierbaustein mit genau einem Parameter (eine Eingangsvariable).
Syntax
<Gültigkeitsbereich> <POU-Name> : <Datentyp des Rückgabewerts> VAR_INPUT <Variablenname> : <Generischer Datentyp>; END_VAR
<Gültigkeitsbereich> | Mögliche Gültigkeitsbereiche:
|
<POU-Name> | Name der POU |
| Optional |
<Variablenname> | Name der Eingangsvariable |
<Generischer Datentyp> |
|
FUNCTION funComputeAny : BOOL
VAR_INPUT
anyInput1 : ANY; // For valid data type see table
END_VAR
FUNCTION_BLOCK FB_ComputeAny
VAR_INPUT
anyInput1 : ANY;
END_VAR
FUNCTION_BLOCK FB_ComputeMethod
METHOD methComputeAnny : BOOL
VAR_INPUT
anyInput1 : ANY_INT; // Valid data types are SINT, INT, DINT, LINT, USINT, UINT, UDINT, ULINT
END_VARTipp
Ab Compilerversion >= 3.5.1.0 werden die in der Tabelle dargestellten generischen IEC-Datentypen unterstützt.
Die Tabelle stellt die Hierarchie der generischen Datentypen dar und gibt Auskunft, welcher generische Datentyp des formalen Parameters (Deklaration) welche elementaren Datentypen des Arguments (Aufruf) erlaubt.
Generischer Datentyp beim formalen Parameter | Erlaubter elementarer Datentyp beim tatsächlichen Parameter (Argument) | ||
|---|---|---|---|
|
|
| |
|
| ||
|
|
| |
|
| ||
|
| ||
Aufruf
Die Syntaxbeschreibungen beziehen sich auf einen Programmierbaustein mit genau einem Parameter, dem ein Argument übergeben wird. Der Datentyp des Arguments konkretisiert dabei den generischen Datentyp der Eingangsvariable. Beispielsweise können Argumente des Typs BYTE, WORD, DWORD, LWORD an eine ANY_BIT-Eingangsvariable übergeben werden.
Syntax Funktionsaufruf:
<Name der Funktion> ( <Argument> )
Syntax Funktionsbausteinaufruf
<Name der Funktinonsbausteininstanz> ( <Name der Eingangsvariable> := <Argument> )
Syntax Methodenaufruf
<Name der Funktionsbausteininstanz> . <Name der Methode> ( <Name der Eingangsvariable> := <Argument> )
<Argument> | Übergabevariable |
PROGRAM PLC_PRG
VAR
byValue : BYTE := 16#AB;
iValue : INT := -1234;
xResultByte : BOOL;
xResultInt : BOOL;
fbComputeAnyByte : FB_ComputeAny;
fbComputeAnyInt : FB_ComputeAny;
fbComputeM1 : FB_ComputeMethod;
fbComputeM2 : FB_ComputeMethod;
byN : BYTE := 1;
wBitField1 : WORD := 16#FFFF;
wBitField2 : WORD := 16#0001;
xInit : BOOL;
xResult : BOOL;
END_VAR
//Implementation
xResultByte := funComputeAny(byValue);
xResultInt := funComputeAny(iValue);
xResult := funGenericCompare(wBitField1, wBitField2);
fbComputeAnyByte(anyInput1 := byValue);
fbComputeAnyInt(anyInput1 := iValue);
fbComputeM1.methComputeAnny(anyInput1 := byValue);
fbComputeM2.methComputeAnny(anyInput1 := iValue);