Zeiger / POINTER
Ein Pointer speichert zur Laufzeit die Speicheradresse von Objekten wie beispielsweise Variablen oder Funktionsbausteininstanzen.
Syntax
<pointer name>: POINTER TO <data type> | <data unit type> | <function block name>;
Beispiel
FUNCTION_BLOCK FB_Sample
VAR
pSample : POINTER TO INT;
nVar1 : INT := 5;
nVar2 : INT;
END_VAR
pSample := ADR(nVar1); // pointer pSample is assigned to address of nVar1
nVar2 := pSample^; // value 5 of nVar1 is assigned to variable nVar2 by dereferencing of pointer pSample
Einen Pointer zu dereferenzieren bedeutet, den Wert zu erhalten, auf den der Pointer zeigt. Ein Pointer wird dereferenziert, indem der Inhaltsoperator ^ an den Pointer-Bezeichner angehängt wird, beispielsweise pSample^ im oben gezeigten Beispiel. Um einem Pointer die Adresse eines Objekts zuzuweisen, verwenden Sie den Adressoperator ADR: ADR(nVar1).
Im Onlinebetrieb können Sie mit dem Befehl Gehe zur Referenz von einem Pointer zur Deklarationsstelle des referenzierten Objekts springen (verfügbar ab TC3.1 Build 4026).
Wenn ein Pointer auf einen lokierte Eingangsvariable verwendet wird, gilt der Zugriff als schreibender Zugriff. Dies führt bei der Codeerzeugung zu der Compilerwarnung "<Pointer Name> ist kein gültiges Zuordnungsziel". Beispiel: Wenn Sie ein Konstrukt dieser Art benötigen, müssen Sie den Eingangswert (nInput) zuerst auf eine Variable mit Schreibzugriff kopieren. |
Indexzugriff auf Pointer
TwinCAT erlaubt den Indexzugriff [ ] auf Variablen vom Typ POINTER, ebenso wie auf die Datentypen STRING oder WSTRING.
Auf die Daten, auf die der Pointer zeigt, kann auch zugegriffen werden, indem der Klammeroperator [ ] an den Pointer-Bezeichner angehängt wird, beispielsweise pData[i]
. Der Basisdatentyp des Pointers bestimmt den Datentyp und die Größe der indizierten Komponente. Der Indexzugriff auf den Pointer erfolgt dabei arithmetisch, indem zur Adresse des Pointers der indexabhängige Offset i * SIZEOF(<base type>)
addiert wird. Gleichzeitig wird der Pointer implizit dereferenziert. Berechnung: pData[i] :=(pData + i * SIZEOF(INT))^
;
Indexzugriff auf STRING
Wenn Sie den Indexzugriff bei einer Variablen vom Typ STRING verwenden, erhalten Sie das Zeichen am Offset des Indexausdrucks. Das Ergebnis ist vom Typ BYTE. Beispielsweise gibt sData[i]
das i-te Zeichen der Zeichenkette sData
als SINT (ASCII) zurück.
Indexzugriff WSTRING
Wenn Sie den Indexzugriff bei einer Variablen vom Typ WSTRING verwenden, erhalten Sie das Zeichen am Offset des Indexausdrucks. Das Ergebnis ist vom Typ WORD. Beispielsweise gibt wsData[i]
das i-te Zeichen der Zeichenkette als INT (Unicode) zurück.
Pointer subtrahieren
Das Ergebnis der Differenz zweier Pointer ist ein Wert vom Typ DWORD, auch auf 64-Bit-Plattformen, wenn die Pointer 64-Bit-Pointer sind.
Beachten Sie die Möglichkeit, Referenzen zu verwenden. Die Verwendung von Referenzen hat den Vorteil, dass Typsicherheit garantiert ist. Das ist bei Pointern nicht der Fall. |
Der Speicherzugriff von Pointern während der Laufzeit kann durch die implizite Überwachungsfunktion CheckPointer geprüft werden. |
Automatische Zeiger-/Referenzaktualisierung beim Online-Change
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.
- Fall 1: Symbol wurde ermittelt
- Wenn das Symbol in den neuen Symbolen, die nach dem Online-Change existieren, noch besteht und wenn sich der Typ des Symbols nicht geändert hat, wird der Zeiger auf das gefundene Symbol umgesetzt. Der Zeiger- bzw. der Adresswert wird aktualisiert.
- Wenn das Symbol in den neuen Symbolen nicht mehr existiert oder wenn sich der Typ des Symbols geändert hat, wird der Zeiger auf null gesetzt.
- Fall 2: Symbol wurde nicht ermittelt
- Wenn ein Zeiger auf eine Adresse verweist, für die auch vor dem Online-Change kein Symbol gefunden wird (z. B. weil der Pointer in einen Speicherbereich außerhalb der SPS zeigt), wird der Zeigerwert beim Online-Change nicht verändert.
Voraussetzungen:
- Für diese Funktion wird die (ADS-) Symbolbeschreibung der Variablen benötigt, auf die der Zeiger verweist. Liegt für eine Variable keine Symbolbeschreibung vor, z. B. aufgrund der Verwendung von Attribut 'hide', wird der Zeiger nicht berücksichtigt.
- Der Zeiger muss auf eine Variable/ein Objekt innerhalb des SPS-Speichers verweisen. Zeiger, die auf einen Speicherbereich außerhalb des SPS-Speichers verweisen, werden beim Online-Change nicht verändert.
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: