Skip to main content

Methodenaufruf

Um einen Methodenaufruf zu implementieren, werden den Schnittstellenvariablen die tatsächlichen Parameter (Argumente) übergeben. Dabei kann alternativ auf die Parameternamen verzichtet werden.

Je nach deklariertem Zugriffsmodifizierer kann eine Methode nur innerhalb des eigenen Namensraums (INTERNAL) , nur innerhalb des eigenen Programmierbausteins und seinen Ableitungen (PROTECTED) oder nur innerhalb des eigenen Programmierbausteins (PRIVATE) aufgerufen werden. Bei PUBLIC kann die Methode überall aufgerufen werden.

Innerhalb der Implementierung kann eine Methode sich selbst rekursiv aufrufen: entweder direkt mit Hilfe des THIS-Pointers, oder mit Hilfe einer lokalen Variablen für den zugeordneten Funktionsbaustein.

Methodenaufruf als virtueller Funktionsaufruf

Durch Vererbung kann es zu virtuellen Funktionsaufrufen kommen.

Virtuelle Funktionsaufrufe ermöglichen, dass derselbe Aufruf in einem Programm-Quellcode während der Laufzeit verschiedene Methoden aufruft.

In folgenden Fällen wird der Methodenaufruf dynamisch gebunden:

  • Sie rufen eine Methode über einen Pointer auf einen Funktionsbaustein auf.

    Beispiel: pfub^.method

    Der Pointer kann in dieser Situation auf Instanzen vom Typ des Funktionsbausteins und auf Instanzen von allen abgeleiteten Funktionsbausteinen zeigen.

  • Sie rufen die Methode einer Schnittstellen-Variablen auf.

    Beispiel: interface1.method

    Die Schnittstelle kann auf alle Instanzen von Funktionsbausteinen verweisen, die diese Schnittstelle implementieren.

  • Eine Methode ruft eine andere Methode desselben Funktionsbausteins auf. Die Methode kann in dem Fall auch die Methode eines abgeleiteten Funktionsbausteins mit gleichem Namen aufrufen.

  • Der Aufruf einer Methode erfolgt über eine Referenz auf einen Funktionsbaustein. Die Referenz kann in dieser Situation auf Instanzen vom Typ des Funktionsbausteins und auf Instanzen von allen abgeleiteten Funktionsbausteinen zeigen.

  • Sie weisen VAR_IN_OUT-Variablen eines Basis-Funktionsbaustein-Typen einer Instanz eines abgeleiteten FB-Typen zu.

    Die Variable kann in dieser Situation auf Instanzen vom Typ des Funktionsbausteins und auf Instanzen von allen abgeleiteten Funktionsbausteinen zeigen.

Beispiel

Beispiel 31. Methoden überladen

Die Funktionsbausteine fub1 und fub2 erweitern den Funktionsbaustein fubbase und implementieren die Schnittstelle interface1. Es gibt die Methoden method1 und method2.

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*)

Unter der Annahme, dass fubbase des oberen Beispiels zwei Methoden method1 und method2 enthält, überschreibt fub1 method2, aber nicht method1. Der Aufruf von method1 erfolgt folgendermaßen:

pInst^.method1();

Wenn b TRUE ist, ruft CODESYSfubbase.method1 auf, ansonsten fub1.method1.



Zusätzliche Ausgänge

Gemäß der Norm IEC 61131-3 können Methoden so wie normale Funktionen zusätzliche Ausgänge deklariert haben. Beim Methodenaufruf weisen Sie den zusätzlichen Ausgängen Variablen zu.

Genaue Informationen hierzu finden Sie beim Thema „Funktion“.

Syntax beim Aufruf

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

Deklaration

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

Autruf

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

Bei Aufruf der Methode werden die Werte der Methodenausgänge auf die lokal deklarierte Ausgabevariablen geschrieben.



Aufruf einer Methode, auch wenn die Applikation im STOP-Status ist

In der Gerätebeschreibung kann definiert sein, dass eine bestimmte Funktionsbaustein-Instanz (eines Bibliotheksbausteins) eine bestimmte Methode immer taskzyklisch aufruft. Wenn die Methode die Eingabeparameter des folgenden Beispiels enthält, arbeitet CODESYS die Methode auch dann ab, wenn die aktive Applikation gerade im STOP-Status ist:

Beispiel 33. Beispiel
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^.udState = 1 THEN <instructions> END_IF;


Methode rekursiv aufrufen

Tipp

Verwenden Sie Rekursionen vorwiegend zur Bearbeitung von rekursiven Datentypen wie beispielsweise verketteten Listen. Allgemein ist es ratsam bei der Verwendung von Rekursion vorsichtig zu sein. Bei einer unerwartet tiefen Rekursion kann es zu einem Stacküberlauf und damit zu einem Maschinenstillstand kommen.

Innerhalb ihrer Implementierung kann eine Methode sich selbst aufrufen:

  • direkt mit Hilfe des THIS-Pointers

  • indirekt mit Hilfe einer lokalen Funktionsbaustein-Instanz des Basisfunktionsbausteins

Üblicherweise wird bei einem solchen rekursiven Aufruf eine Compilerwarnung ausgegeben. Wenn die Methode mit dem Pragma {attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'} versehen ist, wird die Compilerwarnung unterdrückt. Im Kapitel Attribut ‚estimated-stack-usage finden Sie ein Implementierungsbeispiel.