方法调用
为了实现方法调用,实际参数(参数)被传递给接口变量。或者,可以省略参数名称。
根据声明的访问修饰符,方法只能在其自己的命名空间中使用(INTERNAL),仅在自己的编程块及其衍生物内 (PROTECTED)或仅在您自己的编程块内(PRIVATE) 叫做。在 PUBLIC 该方法可以在任何地方调用。
在实现中,方法可以递归地调用自身,或者直接通过 这 指针,或通过指定功能块的局部变量。
方法调用作为虚函数调用
继承会导致虚函数调用。
虚函数调用允许程序源代码中的相同调用在运行时调用不同的方法。
在以下情况下,方法调用是动态绑定的:
您使用指向功能模块的指针调用方法。
例子:
pfub^.method在这种情况下,指针可以指向功能块类型的实例和所有派生功能块的实例。
您调用接口变量的方法。
例子:
interface1.method该接口可以引用实现该接口的功能块的所有实例。
一个方法调用同一个功能模块的另一个方法。在这种情况下,该方法也可以调用同名的派生功能块的方法。
使用对功能模块的引用来调用方法。在这种情况下,引用可以指向功能块类型的实例和所有派生功能块的实例。
你指出
VAR_IN_OUT- 基本功能块类型的变量到派生 FB 类型的实例。在这种情况下,变量可以指向功能块类型的实例以及所有派生功能块的实例。
例子
功能块 fub1 和 fub2 扩展功能块 fubbase 并实现接口 interface1.有方法 method1 和 method2.
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 上面例子中的两种方法 method1 和 method2 包含,覆盖 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>)+ );
宣言
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 状态时,该方法也会启动:
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 查看一个实现示例。