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_TYPE
Tipp
Ü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_VAR
Tipp
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);