Codesys und eine typisierte Liste von Objekten

eedroid

Level-1
Beiträge
20
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Mir fehlt gerade in Codesys eine typisierte Liste von Objekten.

Ich habe folgendes:
Code:
FB_Base
FB_OBJ1 EXTENDS FB_Base IMPLEMENST I_Base
FB_OBJ2 EXTENDS FB_Base IMPLEMENST I_Base
FB_OBJ3 EXTENDS FB_Base IMPLEMENST I_Base

OBJ1 : ARRAY[0..9] OF POINTER TO FB_OBJ1;
LIST1 : FB_LIST;

Code:
FB_LIST
VAR_IN_OUT
    Items : ARRAY
[*] OF POINTER TO FB_Base;
END_VAR
VAR
    INDEX : INT;
END_VAR

Methode zum hinzufuegen von Items:
Code:
FB_LIST.InsertItem

VAR_INPUT
    Item : POINTER TO FB_Base;
END_VAR

Items[INDEX] := item;
INDEX := INDEX + 1;

Meine Frage hierzu: Wie kann ich den FB_LIST mit dem Array verknuepfen? So dass ich bei hinzufuegen und loeschen von Objekten mich immer auf die verknuepfte Liste beziehe.

Folgendes klappt leider nicht, im Programm:
LIST1(Items := OBJ1)



[FEHLER]
C0032: Typ 'POINTER TO ARRAY [0..99] OF POINTER TO FB_OBJ1' kann nicht in Typ 'ARRAY
[*] OF POINTER TO FB_Base' konvertiert werden


Folgenes klappte noch in Version: CODESYS V3.5 SP13 Patch 2
LISTE1.Items := ADR(OBJ1);


Folgendes klappt jetzt aber nicht mehr in Version: CODESYS V3.5 SP14
LISTE1.Items := ADR(OBJ1);



[FEHLER]
C0178: Externer Zugriff auf 'VAR_IN_OUT'-Parameter 'Items' von 'FB_LIST'."



Bin fuer jede Hilfe dankbar, vielen Dank!
 
Zuletzt bearbeitet:
Hai eedroid, bzw. Hai guys,

auch wenn's dir vermutlich nicht mehr hilft @eedroid (2019... ;-)), denke ich, dass es Anderen weiterhelfen könnte.
Ich vermute dir könnte auch das "Linked List"-Pattern helfen?!
Wenn ja, hier gibt's dass schon quelloffen und fertig: https://forge.codesys.com/lib/colist/home/Home/

Ansonsten versuchst du dich an: https://de.wikipedia.org/wiki/Polymorphie_(Programmierung)
Hier zeigt die OOP ihre Stärken und dafür sind eigentlich die Interfaces gedacht.
Hier gibt's auch Freunde der Programmierer, die spaß haben Dinge zu erklären: https://stefanhenneken.net/2014/01/30/iec-61131-3-objektkomposition-mit-hilfe-von-interfaces/


auf deine spezielle Frage:
- VAR_IN_OUT ist zwar auch eigentlich nur eine Referenz, aber von "außen" darauf zuzugreifen ist nicht ganz so sauber... (schon garnicht, wenn die Länge des Arrays auch variable ist und der Inhalt eigentlich nur Pointer sind...)
- POINTER TO FB_Base und POINTER TO FB_Obj1 sind nicht unbedingt gleich, auch wenn Obj1 eine Ableitung von FB_BASE ist...

Ich denke das:
LIST1(Items := OBJ1)
Schon der richtige weg wäre, aber deine Lösung ist ein wenig Pointer auf Pointer auf Pointer...
Weiterhin dirty, aber der schnellste weg:
Code:
FB_Base
FB_OBJ1 EXTENDS FB_Base IMPLEMENST I_Base
FB_OBJ2 EXTENDS FB_Base IMPLEMENST I_Base
FB_OBJ3 EXTENDS FB_Base IMPLEMENST I_Base

OBJ1 : ARRAY[0..9] OF POINTER TO FB_OBJ1;
OBJ1base : ARRAY[0..9] OF POINTER TO FB_Base;
LIST1 : FB_LIST;

FOR i:=0 TO 9 DO
    OBJ1base[i] := OBJ1[i];
END_FOR

LIST1(Items := OBJ1base)


Ein wenig besser, aber wie gesagt für Polymorphie gibt es bessere approaches: (Pointer auf Pointer auf Pointer wird hier umgangen)
Irgendwo in deinem Code muss ja auch das Array[0..9] of OBJ1 liegen, auf welches dein Pointer zeigt?!

OBJ1 eine Ableitung von FB_BASE... Aber POINTER TO FB_BASE ist keine Ableitung von POINTER TO OBJ1... Das sieht zumindest der Kompiler so... Ein schneller Workaroud wäre damit (allerdings nicht ausprobiert):

Code:
FB_LIST
VAR_IN_OUT
    Items : ARRAY[*] OF (*POINTER TO*) FB_Base; // bleibt weiterhin ein call by reference... also hier wird nicht das ganze array kopiert, sondern nur ein Pointer generiert...
END_VAR
VAR
    INDEX : INT;
END_VAR

Code:
FB_LIST
VAR
    // FB_Base
    // FB_OBJ1 EXTENDS FB_Base IMPLEMENST I_Base
    // FB_OBJ2 EXTENDS FB_Base IMPLEMENST I_Base
    // FB_OBJ3 EXTENDS FB_Base IMPLEMENST I_Base
    // ....
 
    OBJ1 : ARRAY[0..9] OF *(POINTER TO*) FB_OBJ1; // ist nun ein Speicherbereich
    OBJ1base : ARRAY[0..9] OF FB_BASE; // workaround für Versuch2
LIST1 : FB_LIST;
END_VAR
VAR
    INDEX : INT;
END_VAR
VAR_TEMP
    i : int;
END_VAR

// Versuch 1:
LIST1(Items := OBJ1);

// Wenn Versuch 1 fehlschlägt:
FOR i:=0 TO 9 DO
    OBJ1base[i] := OBJ1[i];
END_FOR

LIST1(Items := OBJ1base);
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde es über das Inferface versuchen....

Code:
FB_List.M_Add(fbObject1)
....

M_Add
var input
    iObject:    I_Object;
end_var

M_Item : I_Object
var input
    nPosition:    int;
end_var
 
Zurück
Oben