Question about object polymorphism
Home › Forum › Programmazione IEC 61131 (LogicLab) › Question about object polymorphism
- Questo topic ha 4 risposte, 2 partecipanti ed è stato aggiornato l'ultima volta 21 ore, 4 minuti fa da
George.
-
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
PartecipantePROGRAM FBReference1
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_VARIF (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(); -
AutorePost
- Devi essere connesso per rispondere a questo topic.