Say I have an abstract function block AValve
that I extend for various types of valve. I extend that AValve
in order to implement it as a BasicValve
. Also I have a function block that takes an array of AValve
, which looks like this
FUNCTION_BLOCK ValveDispatch
VAR_IN_OUT
valves : ARRAY[*] OF AVALVE;
END_VAR
If I try to pass an array of BasicValve
into this function block, I'm met with:
Cannot convert type 'ARRAY [0..5] OF BasicValve' to type 'ARRAY [*] OF AVALVE' of VAR_IN_OUT 'valves'
Thinking that maybe codesys just couldn't handle both extended types AND variable length arrays at the same time, I've tried doing a set length array as an input, just for testing as I need the variable length. Doing so gives a slightly different error that seems to mean the same thing:
Type `ARRAY[0..5] of BasicValve' is not equal to type 'ARRAY [0..5] OF AVALVE' of VAR_IN_OUT 'valves'
Is there a way I can make this work? Passing a single extended object into an input expecting its base type works fine, but doing so with arrays seems to be unsupported.
The issue you are seeing actually comes down to a pretty simple point, arrays are value datatypes.
That is, when you are trying to pass ARRAY [*] OF FB_Ext
through the VAR_IN_OUT
what you are actually doing is creating a whole new datatype ARRAY [*] OF FB_Ext
which does not extend ARRAY [*] OF FB_Base
.
IF you look at an array at the bit level in ST the issue becomes pretty clear, an array itself has a size of ElementSize * ElementCount
, So trying to force a bigger datatype FB_Ext
into the smaller dataspace of FB_Base
is not going to work without messing everything up.
So you will have to do this handling with either pointers or interfaces.
TLDR: What you want to do is not possible in ST.
So this was originally going to be a comment, but it got a bit beyond the size limit. Posted as a wiki instead.