方法调用
为了实现方法调用,实际参数(参数)被传递给接口变量。或者,可以省略参数名称。
根据声明的访问修饰符,方法只能在其自己的命名空间中使用(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 查看一个实现示例。