Search code examples
twincatcodesys

How do I pass an array of an extended type in codesys/twincat3?


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.


Solution

  • 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.