REFERENCE

Eine Referenz verweist implizit auf ein anderes Objekt. Beim Zugriff wird die Referenz implizit dereferenziert, und benötigt deswegen keinen speziellen Inhaltsoperator ^ wie ein Pointer.

Syntax

<identifier> : REFERENCE TO <data type> ;
<data type>  : base type of the reference

Beispieldeklaration:

PROGRAM_MAIN
VAR
    refInt  : REFERENCE TO INT;
    nA      : INT;
    nB      : INT;
END_VAR

Sie können nun refInt als „Alias“ für Variablen des Typs INT verwenden.

Zuweisung:

Die Adresse der Referenz müssen Sie über eine separate Zuweisungsoperation mit Hilfe des Zuweisungsoperators REF= setzen. Eine Ausnahme hiervon besteht, wenn ein Input ein REFERENCE TO ist und der Input innerhalb des Aufrufs übergeben wird. Dann wird anstelle des Zuweisungsoperators REF= der normale Zuweisungsoperator := verwendet.

FUNCTION_BLOCK FB_Sample
VAR_INPUT
    refInput1  : REFERENCE TO INT;
    refInput2  : REFERENCE TO INT;
END_VAR
PROGRAM MAIN
VAR
    fbSample   : FB_Sample;
    n1         : INT;
    n2         : INT;
END_VAR
fbSample.refInput1 REF= n1;
fbSample(refInput2   := n2);

Ob eine Referenz auf einen gültigen Wert (zum Beispiel ungleich 0) zeigt, können Sie mithilfe eines speziellen Operators überprüfen (siehe Referenzen auf Gültigkeit prüfen).

Anwendungsbeispiel:

refInt REF= nA;         // refInt points now to nA
refInt   := 12;         // nA has got the value 12
nB       := refInt * 2; // nB has got the value 24
refInt REF= nB;         // refInt points now to nB
refInt   := nA / 2;     // nB has got the value 6
refInt REF= 0;          // explicit initialisation of the reference
REFERENCE 1:

TwinCAT initialisiert Referenzen (mit 0).

REFERENCE 2:

Wenn eine Referenz auf eine lokierte Eingangsvariable verweist, gilt der Zugriff (beispielsweise rInput REF=Input;) als schreibender Zugriff. Dies ist nicht möglich und führt bei der Codeerzeugung zu einem Compilerfehler.

Zuweisungsoperator REF=

Der Operator erzeugt eine Referenz (Pointer) auf einen Wert.

Syntax:

<variable name> REF= <variable name>

Beispiel:

PROGRAM MAIN
VAR
    refA  : REFERENCE TO ST_Sample;
    stA   : ST_Sample;
    refB  : REFERENCE TO ST_Sample;
    stB1  : ST_Sample;
    stB2  : ST_Sample;
END_VAR
refA REF= stA;   // represents => refA  := ADR(stA);
refB REF= stB1;  // represents => refB  := ADR(stB1);
refA := refB;    // represents => refA^ := refB^; (value assignment of refB as refA and refB are implicitly dereferenced)
refB := stB2;    // represents => refB^ := stB2; (value assignment of stB2 as refB is implicitly dereferenced)
END_VAR

Ungültige Deklarationen

PROGRAM MAIN
VAR
     aTest      : ARRAY[0..9] OF REFERENCE TO INT;
     pTest      : POINTER TO REFERENCE TO INT;
     refTestRef : REFERENCE TO REFERENCE TO INT;
     refTestBit : REFERENCE TO BIT;
END_VAR

Ein Referenztyp darf nicht als Basistyp eines Arrays, Pointers oder einer Referenz verwendet werden. Außerdem darf eine Referenz nicht auf eine Bit-Variable verweisen. Solche Konstrukte erzeugen Compilerfehler.

Vergleich von Referenz und Pointer

Eine Referenz hat gegenüber einem Pointer folgende Vorteile:

Referenzen auf Gültigkeit prüfen

Sie können den Operator __ISVALIDREF verwenden, um zu prüfen, ob eine Referenz auf einen gültigen Wert weist, das heißt auf einen Wert ungleich 0.

Syntax:

<boolesche Variable> := __ISVALIDREF(<mit REFERENCE TO <datatype> deklarierter Kennzeichner>);

Die boolesche Variable wird TRUE, wenn die Referenz auf einen gültigen Wert zeigt, andernfalls FALSE.

Beispiel

PROGRAM_MAIN
VAR
    nVar      : INT;
    refInt1   : REFERENCE TO INT;
    refInt2   : REFERENCE TO INT;
    bTestRef1 : BOOL := FALSE;
    bTestRef2 : BOOL := FALSE;
END_VAR
nVar       := nVar + 1;
refInt1  REF= nVar;
refInt2  REF= 0;
bTestRef1  := __ISVALIDREF(refInt1); (* becomes TRUE, because refInt1 points to nVar, which is non-zero *)
bTestRef2  := __ISVALIDREF(refInt2); (* becomes FALSE, because refInt2 is set to 0 *)
REFERENCE 3:

Die implizite Überwachungsfunktion Checkpointer wirkt auch auf Variablen vom Typ REFERENCE in gleicher Weise wie auf Zeigervariablen.

Automatische Zeiger-/Referenzaktualisierung beim Online-Change

REFERENCE 4:

Verfügbar ab TwinCAT 3.1 Build 4026

Die nachfolgenden Beschreibungen beziehen sich sowohl auf Zeiger als auch auf Referenzen. Für eine vereinfachte Lesbarkeit wird im Folgenden jedoch nur der Begriff des Zeigers verwendet.

Funktion:

Bei einem Online-Change werden die Werte aller SPS-Zeiger automatisch aktualisiert, sodass der jeweilige Zeiger auf die gleiche Variable bzw. auf das gleiche Objekt verweist wie vor dem Online-Change. Dadurch behält ein Zeiger nach dem Online-Change seine Gültigkeit, auch wenn die Variable, auf die gezeigt wird, während des Online-Changes an eine andere Speicherposition verschoben wird.

Funktionsweise:

Bei einem Online-Change wird für jeden Zeiger geprüft, ob dieser auf ein SPS-Symbol verweist. Für eine solche Ermittlung müssen die u. g. Voraussetzungen erfüllt sein.

Voraussetzungen:

Zusätzliche Aktualisierungsmöglichkeit:

Die beschriebene Funktionalität steht ab TwinCAT 3.1 Build 4026 zur Verfügung. Ein ggf. bisheriger, manuell implementierter Mechanismus zur Aktualisierung eines Zeigers kann weiterhin verwendet werden. Hierbei kann dem Zeiger z. B. zyklisch das gewünschte Ziel zugewiesen werden. Es besteht keine Notwendigkeit, diese Codezeilen aus dem Projekt zu entfernen. Gleichermaßen ist es nicht erforderlich, diese Codezeilen zu behalten bzw. zu implementieren.

Siehe auch: