Skip to main content

方法调用

为了实现方法调用,实际参数(参数)被传递给接口变量。或者,可以省略参数名称。

根据声明的访问修饰符,方法只能在其自己的命名空间中使用(INTERNAL),仅在自己的编程块及其衍生物内 (PROTECTED)或仅在您自己的编程块内(PRIVATE) 叫做。在 PUBLIC 该方法可以在任何地方调用。

在实现中,方法可以递归地调用自身,或者直接通过 指针,或通过指定功能块的局部变量。

方法调用作为虚函数调用

继承会导致虚函数调用。

虚函数调用允许程序源代码中的相同调用在运行时调用不同的方法。

在以下情况下,方法调用是动态绑定的:

  • 您使用指向功能模块的指针调用方法。

    例子: pfub^.method

    在这种情况下,指针可以指向功能块类型的实例和所有派生功能块的实例。

  • 您调用接口变量的方法。

    例子: interface1.method

    该接口可以引用实现该接口的功能块的所有实例。

  • 一个方法调用同一个功能模块的另一个方法。在这种情况下,该方法也可以调用同名的派生功能块的方法。

  • 使用对功能模块的引用来调用方法。在这种情况下,引用可以指向功能块类型的实例和所有派生功能块的实例。

  • 你指出 VAR_IN_OUT- 基本功能块类型的变量到派生 FB 类型的实例。

    在这种情况下,变量可以指向功能块类型的实例以及所有派生功能块的实例。

例子

31. 方法重载

功能块 fub1fub2 扩展功能块 fubbase 并实现接口 interface1.有方法 method1method2.

PROGRAM PLC_PRG
VAR_INPUT
  b : BOOL;
END_VAR

VAR  pInst : POINTER TO fubbase;
  instBase : fubbase;
  inst1 : fub1;
  inst2 : fub2;
  instRef : REFERENCE to fubbase;
END_VAR

IF b THEN
  instRef REF= inst1;            (* reference to fub1 *)
  pInst := ADR(instBase);
ELSE
  instRef REF= inst2;            (* reference to fub2  *)
  pInst := ADR(inst1);
END_IF
pInst^.method1();            (* If b is TRUE, fubbase.method1 will be called, otherwise fub1.method1 is called *)
instRef.method1();        (* If b ist TRUE, fub1.method1 will be called, otherwise fub2.method1 is called*)

假如说 fubbase 上面例子中的两种方法 method1method2 包含,覆盖 fub1 method2, 但不是 method1.的呼唤 method1 发生如下:

pInst^.method1();

什么时候 b TRUE 是,调用 CODESYSfubbase.method1 向上,否则 fub1.method1.



额外的出口

根据 IEC 61131-3 标准,方法与正常功能一样,可以声明附加输出。调用该方法时,您将变量分配给其他输出。

您可以在“功能”主题下找到这方面的详细信息。

调用时的语法

<function block name>.<method name>(<first input name> := <value> (, <further input assignments>)+ , <first output name> => <first output variable name> (,<further output assignments>)+ );
32. 例子

宣言

METHOD PUBLIC DoIt : BOOL
VAR_INPUT
        iInput_1 : DWORD;
        iInput_2 : DWORD;
END_VAR
VAR_OUTPUT
        iOutput_1 : INT;
        sOutput_2 : STRING;
ENDVAR

称呼

fbInstance.DoIt(iInput_1 := 1, iInput_2 := 2, iOutput_1 => iLocal_1, sOUtput_2 => sLocal_2);

当方法被调用时,方法输出的值被写入本地声明的输出变量。



即使应用程序处于 STOP 状态也调用方法

可以在设备描述中定义某个功能块实例(库块的)在一个任务周期中总是调用某个方法。如果该方法采用以下示例的输入参数,则它可以工作 CODESYS 当活动应用程序当前处于 STOP 状态时,该方法也会启动:

33. 例子
VAR_INPUT
        pTaskInfo : POINTER TO DWORD;
        pApplicationInfo: POINTER TO _IMPLICIT_APPLICATION_INFO;
END_VAR

(*Now the status of the application can be queried via pApplicationInfo and the instructions can be implemented: *)

IF pApplicationInfo^.udState = 1 THEN <instructions> END_IF;


递归调用方法

提示

主要使用递归来操作递归数据类型,例如链表。通常,建议在使用递归时要小心。意外的深度递归可能导致堆栈溢出,从而导致机器停止。

在其实现中,方法可以调用自身:

  • 直接通过 指针

  • 间接使用基本功能块的本地功能块实例

这种递归调用通常会发出编译器警告。如果带有pragma的方法 {attribute 'estimated-stack-usage' := '<estimated stack size in bytes>'} 提供,编译器警告被抑制。在章节中 属性 'estimated-stack-usage 查看一个实现示例。