Pointer auf Array - Dereferenzierung

ksc

Level-1
Beiträge
31
Reaktionspunkte
14
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich bin zur Zeit am Programmieren einer SPS mit TwinCAT in Strukturierter Text. Dabei bin ich auf ein Problem gestoßen:
Ich übergebe einem Funtionsblock eine Struktur die folgendermaßen aussieht:

Code:
TYPE user_struct :
STRUCT
    pWorkArray_ADR       : POINTER TO LREAL := 0;
    nWorkArray_SIZEOF   : UINT             := 0;
END_STRUCT
END_TYPE

Also ein Pointer auf ein Array vom Typ LREAL und die Größe des Array.

Nun möchte ich innerhalb des FB auf die einzelnen Elemente des durch den Poniter übergebenen Array's zugreifen.
Leider hab ich noch keine Möglichkeit den Pointer auf das Array korrekt zu dereferenzieren...

Ich habe schon folgendes probiert:

Code:
user_struct_var.pWorkArray_ADR^[i];
(user_struct_var.pWorkArray_ADR)^[i];
(user_struct_var.pWorkArray_ADR^)[i];
user_struct_var.pWorkArray_ADR[i]^;
user_struct_var.pWorkArray_ADR[i];

wobei i die Laufvariable von einer FOR-Schleife ist.

Leider kommt immer der Fehler: 4110: '[<index>]' ist nur für Arrayvariablen zulässig

In der Hilfe von TwinCAT oder Codesys bin ich leider nicht fündig geworden und auch das Internet
hat nicht weiterhelfen können...

Ich hoffe ihr könnt mir einen Hinweis geben.

Danke.
 
Wenn die Größe deines Array nicht konstant ist, wirst du nicht um Zeigerarithmetik herumkommen.

Ist die Arraygröße konstant, könntest du den Pointertyp direkt angeben, z.B,
Code:
pWorkArray_ADR       : POINTER TO ARRAY[0..9] OF LREAL

So wie du es jetzt hast kannst du nicht auf die Array-Elemente mittels Array-Index zugreifen, sondern das wäre dann nur mit Zeigerarithmetik möglich.

Dann müsstest du den Zeiger auf das erste Element des Arrays setzen, dann kannst du den Zeiger immer um ein Element erhöhen:
Code:
pWorkArray_ADR := pWorkArray_ADR + SIZEOF(pWorkArray_ADR^);
 
Zuletzt bearbeitet:
Hab grade den letzten Eintrag geändert, denn das geht so nicht.
Was aber geht (steht so auch in der Hilfe) ist, nicht den Zeiger zu verändern sondern erst eine Adresse vom Typ UDINT daraus zu machen und mit dieser den Offset zu berechnen.

Zusätzliche Variable anlegen und einen 'Arbeitszeiger' damit man den Zeiger auf den Index 0 nicht ändert:
Code:
uiAdrWorkArray : UDINT;
pWorkPtr : POINTER TO LREAL;

und dann
Code:
i := 5;
uiAdrWorkArray := pWorkArray_ADR;
pWorkPtr := uiAdrWorkArray + i * SIZEOF(pWorkPtr^);

foo := pWorkPtr^;

Schön ist aber was anderes ;-)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Immer beachten! Ich meine, die Sache mit der Pointer Arithmetik nicht in der IEC Norm geregelt, also letztendlich vom Hersteller des Compilers abhängig.

Soweit ich weiss, ist in Codesys 2.x alle Arithmetik Byte basiert also nicht wie in C und verwandten Sprachen an den Datentyp des Objektes angepasst.

Es ist also wildes Casten (Typumwandlung) und vorsichtiges Rechnen angesagt, es gibt keinen doppelten Boden bei Laufzeitfehlern und alles stürzt ab, wenn mann daneben greift.
 
Zurück
Oben