在我的项目中,我开发了 FB_Modes,它允许我根据模式执行某些操作。这些 FB 实现相同的 I_Mode 接口。
为了检查哪种模式处于活动状态,我想将当前的 I_Mode 与 FB 进行比较,但 Twincat 不允许直接比较 FB 与接口。我希望能够做这样的事情。
IF fbMachine.itfActualMode = fbMode2 THEN
<Do something>
END_IF
有办法做到这一点吗?或者另一种方法直接将FB与接口与地址进行比较。
为了解决这个问题,我为每个 FB 使用了一个唯一的属性。但我使用 STRING 比较,我认为这个解决方案不干净。
IF fbMachine.itfActualMode.sName = fbMode2.sName THEN
<Do something>
END_IF
我曾经尝试使用内置的 __QUERYPOINTER 函数来检查当前接口是否是指定 FunctionBlock 的实例,但是,正如文档末尾所述(您必须确保类型。例如,该接口可以提供一个返回类型代码的方法。),但它不起作用。唯一明智的做法似乎是按照文档中建议的引用,向接口添加一个方法/属性,以提供有关当前类型的信息,正如您已经得出的结论。
我建议做的唯一一件事可能是返回一个自定义枚举而不是字符串,这将允许您检查 case-of 语句中的类型:
result := '';
fbType := _interface.GetType();
CASE fbType OF
FbType.FB1: result := 'FB1';
FbType.FB2: result := 'FB2';
ELSE
result := 'unknown';
END_CASE
一种解决方案是向 I_Mode 添加方法
Equals()
,然后在功能块中实现它。想法是创建一个临时接口,然后比较它们是否匹配。
METHOD Equals : BOOL
VAR_INPUT
Compare : I_Mode;
END_VAR
VAR
Temp : I_Mode;
END_VAR
//Code starts
Temp := THIS^;
Equals := Compare = Temp;
然后你可以像这样检查FB是否等于接口
IF fbMachine.itfActualMode.Equals(fbMode2) THEN
//...
END_IF