The data types ANY
or ANY_<type>
are used in interfaces of functions, function blocks, or methods in order to type
input parameters whose type is unknown or unspecified: The input variables (VAR_INPUT
) have a generic data type.
The compiler replaces the type of input variable internally with the data structure described below, whereby the value is not passed directly. Instead, a pointer is passed to the actual value so only a variable can be passed. Therefore, the data type is only specified when it is called. As a result, calls of such POUs can be made using arguments which each have different data types.
Literals, replaced constants, and results of function calls or expressions cannot be passed to input variables (VAR_IN_OUT
).
Internal data structure for 'ANY' and 'ANY_<type>'
When code is compiled, the input variables are typed internally with ANY
data type by the following structure. When the POU is called (at runtime), the argument
is passed to a reference parameter.
TYPE AnyType : STRUCT // the type of the actual parameter typeclass : __SYSTEM.TYPE_CLASS ; // the pointer to the actual parameter pvalue : POINTER TO BYTE; // the size of the data, to which the pointer points diSize : DINT; END_STRUCT END_TYPE
You can access the input variable within the POU via this structure by means of this structure, and for example query the passed value.
Example
This compares whether or not two input variables have the same type and the same value.
FUNCTION funGenericCompare : BOOL VAR_INPUT any1 : ANY; any2 : ANY; END_VAR VAR pTest : POINTER TO ARRAY [0..100] OF POINTER TO DWORD; diCount: DINT; END_VAR 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; // END_FUNCTION
Declaration
The syntax descriptions refer to a POU with exactly one parameter (an input variable).
Syntax
FUNCTION | FUNCTION_BLOCK | METHOD <POU name> ( : <return data type> )? VAR_INPUT <input variable name> : <generic data type>; END_VAR <generic data type> = ANY | ANY_BIT | ANY_DATE | ANY_NUM | ANY_REAL | ANY_INT | ANY_STRING
Example
FUNCTION funComputeAny : BOOL VAR_INPUT anyInput1 : ANY; // valid data type see table END_VAR // END_FUNCTION FUNCTION_BLOCK FB_ComputeAny VAR_INPUT anyInput1 : ANY; END_VAR // END_FUNCTION_BLOCK 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 //END_METHOD
With compiler versions > 3.5.1.0, the generic IEC data types in the table are supported.
The table represents the hierarchy of the generic data types and provides information as to which generic data type of the formal parameter (declaration) allows which elementary data types of the argument (call).
Generic data type in the case of a formal parameter |
Permitted elementary data type in the case of an actual parameter (argument) |
||
---|---|---|---|
|
|
|
|
|
|
||
|
|
|
|
|
|
||
|
|
Call
The syntax descriptions refer to a POU with exactly one parameter, to which an argument
is passed. As a result, the data type of the argument specifies the generic data type
of the input variable. For example, arguments of the type BYTE, WORD, DWORD, LWORD
can be passed to a type ANY_BIT
input variable.
Syntax of function call
<variable name> := <function name> ( <argument name> ); <argument name> : variable with valid data type
Syntax of function block call
<function block name> ( <input variable name> := <argument name> );
Syntax of method call
<function block name> . <method name> ( <input variable name> := <argument name> );
Example
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 xResultByte := funComputeAny(byValue); xResultInt := funComputeAny(iValue); xResult := funGenericCompare(wBitField1, wBitField2); fbComputeAnyByte(anyInput1 := byValue); fbComputeAnyInt(anyInput1 := iValue); fbComputeM1.methComputeAnny(anyInput1 := byValue); fbComputeM2.methComputeAnny(anyInput1 := iValue); // END_PRG