Calling Methods - Virtual Function Call

Virtual function calls can occur due to inheritance.

Virtual function calls enable one and the same call to call various methods in a program source code during the runtime.

In the following cases the method call is dynamically bound:

  • You call a method via a pointer to a function block (for example pfub^.method).

    In this situation the pointer can point to instances of the type of the function block and to instances of all derived function blocks.

  • You call a method of an interface variable (for example interface1.method).

    The interface can refer to all instances of function blocks that implement the interface.

  • A method calls another method of the same function block. In this case the method can also call the method of a derived function block with the same name.

  • The call of a method takes place by means of a reference to a function block. In this situation the reference can point to instances of the type of the function block and to instances of all derived function blocks.

  • You assign VAR_IN_OUT variables of a basic function block type to an instance of a derived FB type.

    In this situation the variable can point to instances of the type of the function block and to instances of all derived function blocks.

In accordance with the IEC 61131-3 standard methods can, like normal functions, have additional outputs. You assign the outputs with the method call. Precise information about this can be found in the topic “Function”.

<method>(in1:=<value> \\\| further input assignments, out1 => <output variable1> \\\| out2 => <output variable2> \\\| further output variables)

The effect of this is that CODESYS writes the output of the method, as defined in the call, to the locally declared output variable.

Example

The function blocks fub1 and fub2 extend the function block fubbase and implement the interface interface1. The methods method1 and method2 exist.

PROGRAM PLC_PRG
VAR_INPUT
b : BOOL;
END_VAR

VAR  pInst : POINTER TO fubbase;
instBase : fubbase;
inst1 : fub1;
inst2 : fub2;
instRef : REFERENCE to fubbase;
END_VAR

IF b THEN
instRef REF= inst1;            (* reference to fub1 *)
pInst := ADR(instBase);
ELSE
instRef REF= inst2;            (* reference to fub2  *)
pInst := ADR(inst1);
END_IF
pInst^.method1();            (* If b is TRUE, fubbase.method1 will be called, otherwise fub1.method1 is called *)
instRef.method1();        (* If b is TRUE, fub1.method1 will be called, otherwise fub2.method1 is called*)

On the assumption that fubbase in the above example contains two methods method1 and method2, it overwrites fub1 method2, but not method1. The call of method1 takes place as follows:

pInst^.method1();

If b is TRUE, CODESYS calls fubbase.method1, otherwise fub1.method1.

See also

Calling a method even if the application is in the STOP state

In the device description it is possible to define that a certain function block instance (of a library function block) always calls a certain method in each task cycle. If the method contains the input parameters of the following example, CODESYS processes the method even if the active application is presently in the STOP state:

Example

VAR_INPUT
pTaskInfo : POINTER TO DWORD;
pApplicationInfo: POINTER TO _IMPLICIT_APPLICATION_INFO;
END_VAR
(*Now the status of the application can be queried via pApplicationInfo
and the instructions can be implemented: *)

IF pApplicationInfo^.state = RUNNING THEN <instructions> END_IF;