Question about object polymorphism
Home › Forum › Programmazione IEC 61131 (LogicLab) › Question about object polymorphism
- Questo topic ha 5 risposte, 2 partecipanti ed è stato aggiornato l'ultima volta 2 settimane, 4 giorni fa da
Sergio Bertana.
-
AutorePost
-
Maggio 15, 2025 alle 11:16 am #82249
George
PartecipanteIs it possible to assign dynamically a FB pointer to an Interface type ?
Maggio 15, 2025 alle 11:17 am #82251Sergio Bertana
Amministratore del forumYes, also in LogicLab as in many modern IEC 61131-3 environments such as TwinCAT 3, Codesys v3.x, it is possible to dynamically assign a Function Block (FB) to a variable of interface type, provided that the FB implements that interface. The idea is that you can use an interface as an abstract type and dynamically assign an FB that implements it usually through pointer dereferencing (^) or a type cast.
You can download Polymorphism a LogicLab program with an example of use the polymorphism, essentially referring to the screenshot yo can see the Form interface that refer to a trigonometric figure that has two method prototypes.
- Area: This method calculates the area of the form
- Perimeter: This method calculates the perimeter of the form
Then two FBs are been defined each implement the Form interface, with the code to calculate the perimeter and area of the relate trigonometric figure. In the FBReference program the RForm variable of Form interface type is istantiated. Then by referencing RForm to different trigonometric figure is possible to calculate perimeter and area of them.
Maggio 15, 2025 alle 3:25 pm #82260George
PartecipanteIf I would instantiate Square and Rectangle FBs dynamically (SysMalloc) as the example
IF (SysFirstLoop) THEN MySquare:=SysMAlloc(SIZEOF(Square)); MyRectangle:=SysMAlloc(SIZEOF(Rectangle)); @MySquare.Side:=10; //Square side @MyRectangle.Width:=20; //Rectangle width @MyRectangle.Height:=4; //Rectangle height END_IF;
is it possible?
Maggio 15, 2025 alle 5:31 pm #82272Sergio Bertana
Amministratore del forumI’ve rewritten your program in a form I supposed was correct but there’s two compiling errors.
VAR SquareArea : REAL; (* Square area *) SquarePerimeter : REAL; (* Square perimeter *) RectangleArea : REAL; (* Rectangle area *) RectanglePerimeter : REAL; (* Rectangle perimeter *) RForm : Form; (* Reference to Form *) MySquare : Square^; (* Reference to Square *) MyRectangle : Rectangle^; (* Reference to Rectangle *) END_VAR // Program initializations. IF (SysFirstLoop) THEN // MySquare:=SysMAlloc(SIZEOF(Square)); // MyRectangle:=SysMAlloc(SIZEOF(Rectangle)); MySquare^.Side:=10; //Square side MyRectangle^.Width:=20; //Rectangle width MyRectangle^.Height:=4; //Rectangle height END_IF; // Calculates area and perimeter. RForm:=MySquare^; //Reference to Form SquareArea:=RForm.Area(); //Square area SquarePerimeter:=RForm.Perimeter(); //Square perimeter RForm:=MyRectangle^; //Reference to Form RectangleArea:=RForm.Area(); //Rectangle area RectanglePerimeter:=RForm.Perimeter(); //Rectangle perimeter
I’ve to ask to Axel support how to manage this scenario.
I’ve a question, why you would dynamically instantiate the FBs? Is not easiest simply instantiate they in the data memory?
Maggio 16, 2025 alle 4:18 pm #82315George
PartecipanteIn LogicLab program i write a program like this:
VAR SquareArea : REAL; (* Square area *) SquarePerimeter : REAL; (* Square perimeter *) RectangleArea : REAL; (* Rectangle area *) RectanglePerimeter : REAL; (* Rectangle perimeter *) RForm : Form; (* Reference to Form *) MySquare : Square; (* Square form *) MyRectangle : Rectangle; (* Rectangle form *) pMySquare : @Square; pMyRectangle : @Rectangle; END_VAR IF (SysFirstLoop) THEN CASE select OF 1: pMySquare:= SysMAlloc(SIZEOF(Square)); RForm:=@pMySquare; //Reference to Form 2: pMyRectangle:= SysMAlloc(SIZEOF(Rectangle)); RForm:=@pMyRectangle; //Reference to Form END_CASE; END_IF; CASE select OF 1: SquareArea:=RForm.Area(); //Square area SquarePerimeter:=RForm.Perimeter(); //Square perimeter 2: RectangleArea:=RForm.Area(); //Rectangle area RectanglePerimeter:=RForm.Perimeter(); //Rectangle perimeter END_CASE;
In TWINCAT we could write
pMySquare:= _NEW(Square); RForm:= pMySquare^; RForm.Area(); RForm.Perimeter();
Maggio 19, 2025 alle 8:50 am #82351Sergio Bertana
Amministratore del forumSorry but i don’t understand your needs why you have to dynamically allocate the FBs. You need use them and then you destroy after use? and why you have to destroy them you need to save memory?
To obtain the same result as in the TWINCAT with LogicLab program you can write:
VAR SquareArea : REAL; (* Square area *) SquarePerimeter : REAL; (* Square perimeter *) RForm : Form; (* Reference to Form *) MySquare : Square; (* Square form *) END_VAR MySquare.Side:=10; //Square side RForm:=MySquare; //Reference to Form SquareArea:=RForm.Area(); //Square area SquarePerimeter:=RForm.Perimeter(); //Square perimeter
You simply static instantiate the objects and use them.
-
AutorePost
- Devi essere connesso per rispondere a questo topic.