Calling Methods

To implement a method call, the actual parameters (arguments) are passed to the interface variables. As an alternative, the parameter names can be omitted.

Depending on the declared access modifier, a method can be called only within its own namespace (INTERNAL), only within its own programming module and its derivatives (PROTECTED), or only within its own programming module (PRIVATE). For PUBLIC, the method can be called from anywhere.

Within the implementation, a method can call itself recursively, either directly by means of the THIS pointer, or by means of a local variable for the assigned function block.

Method call as a 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 the method of an interface variable (for example interface1.method).

    The interface can refer to all instances of function blocks that implement this 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.

Example

Overloading methods

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 ist 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, then CODESYS calls fubbase.method1. If not, then fub1.method1 is called.

Additional outputs

In accordance with the IEC 61131-3 standard, methods can have additional outputs declared, like normal functions. With the method call, you assign variables to the additional outputs.

Detailed information about this can be found in the topic “Function”.

Syntax for the call:

<function block name>.<method name>(<first input name> := <value> (, <further input assignments>)+ , <first output name> => <first output variable name> (,<further output assignments>)+ );

Example

Declaration

METHOD PUBLIC DoIt : BOOL
VAR_INPUT
    iInput_1 : DWORD;
    iInput_2 : DWORD;
END_VAR
VAR_OUTPUT
    iOutput_1 : INT;
    sOutput_2 : STRING;
ENDVAR

Call

fbInstance.DoIt(iInput_1 := 1, iInput_2 := 2, iOutput_1 => iLocal_1, sOUtput_2 => sLocal_2);

When the method is called, the values of the method outputs are written to the locally declared output variables.

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;

Calling methods recursively

Note

Use recursions mainly for processing recursive data types such as linked lists. Generally, we recommend that you be careful when using recursion. An unexpectedly deep recursion can lead to stack overflow and therefore to machine downtime.

Within their implementation, a method can call itself:

  • Directly by means of the THIS pointer
  • Indirectly by means of a local function block instance of the basic function block

Usually, a compiler warning is issued for such a recursive call. If the method is provided with the pragma {attribute 'estimated-stack-usage' := '<sstimated_stack_size_in_bytes>'}, then the compiler warning is suppressed. For an implementation example, refer to the section “Attribute ‘estimated-stack-usage’”.

See also