# 调用方法

为了实现方法调用，将实际参数（参数）传递给接口变量。或者，可以省略参数名称。

根据声明的访问说明符，只能在自己的命名空间（INTERNAL）中或自己的编程模块及其派生类（PROTECTED）或仅在自己的编程模块（PRIVATE）中调用方法。对于PUBLIC，可以从任何地方调用该方法。

在实现中，方法可以直接通过THIS指针或通过所分配功能块的局部变量来递归调用自己。

### 作为虚拟函数调用的方法调用​

由于继承，可能会发生虚拟函数调用。

虚拟函数调用允许在运行时通过同一调用来调用程序源代码中的各种方法。

在以下情况下，方法调用是动态绑定的：

- 您可以通过指向功能块的指针（例如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，然后MetaFacture调用fubbase.method1。如果不是，则调用fub1.method1。

附加输出​
根据IEC 61131-3标准，方法可以声明其他输出，例如正常功能。通过方法调用，可以将变量分配给其他输出。

有关此内容的详细信息，请参见“函数”主题。

调用语法：

.( := (, )+ , => (,)+ );

> 例

> 声明

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

> .Call

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

> 调用方法时，方法输出的值将写入本地声明的输出变量。

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

在设备描述中，可以定义某个功能块实例（库功能块的实例）在每个任务周期中始终调用某种方法。如果该方法包含以下示例的输入参数，MetaFacture则即使活动的应用程序当前处于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^.state = RUNNING THEN END_IF;

### 递归调用方法

在其实现中，方法可以自行调用：

- 直接通过THIS指针
- 间接通过局部功能块实例化本地功能块

通常，会为此类递归调用发出编译器警告。如果该方法提供了实用说明{attribute'estimated-stack-usage'：=''}，则将禁止编译器警告。有关实现示例，请参见“属性'estimated-stack-usage'”一节。