如何在Codesys/TwinCAT3中传递继承基类的扩展类型数组参数?
问题根因
该报错是IEC 61131-3标准的类型匹配规则直接导致的:
VAR_IN_OUT参数要求类型严格全等,不支持数组的协变特性。虽然单个
BasicValve实例可以隐式转换为基类AValve,但ARRAY OF BasicValve和ARRAY OF AValve属于完全不同的类型,无论是可变长数组ARRAY[*]还是固定长度数组,都无法直接兼容。
可行解决方案
方案1:改用指针数组传递(改造成本最低)
把功能块的输入输出参数改为接收基类指针的可变长数组,调用端提前把派生类实例的地址填充到指针数组中即可:
调整后ValveDispatch定义:FUNCTION_BLOCK ValveDispatch VAR_IN_OUT valves : ARRAY[*] OF POINTER TO AVALVE; END_VAR调用端代码示例:
// 你的派生类实例数组 basicValves: ARRAY[0..5] OF BasicValve; // 适配用的基类指针数组 valvePtrs: ARRAY[0..5] OF POINTER TO AValve; // 初始化指针数组 FOR i := 0 TO 5 DO valvePtrs[i] := ADR(basicValves[i]); END_FOR // 调用功能块 ValveDispatch(valves := valvePtrs);功能块内部访问阀门方法/属性时,需要用
^解引用:valves[i]^.Open();方案2:用接口替代抽象功能块继承(更规范的面向对象实现)
将原来的抽象基类AValve改为接口IValve,所有阀门类实现该接口,接口类型的数组天然支持协变,无需额外适配:
接口定义示例:INTERFACE IValve METHOD Open METHOD Close METHOD GetState: BOOL END_INTERFACE阀门功能块实现接口:
FUNCTION_BLOCK BasicValve IMPLEMENTS IValve // 实现IValve定义的所有方法 END_FUNCTION_BLOCK调整后
ValveDispatch定义:FUNCTION_BLOCK ValveDispatch VAR_IN_OUT valves : ARRAY[*] OF IValve; END_VAR此时可以直接将
BasicValve类型的数组传入功能块,无需转换。方案3:遍历数组逐个调用(适合逻辑简单的场景)
如果不需要一次性传递整个数组到功能块,可在调用端遍历BasicValve数组,逐个将单个实例传入接收基类AValve的处理逻辑,不需要修改原有基类和功能块的定义。
内容的提问来源于stack exchange,提问作者Taeo
相关产品推荐
相关产品推荐

