指针

概述

作为 IEC 61131-3 标准的扩展,您可以使用指针。

指针能够在应用程序运行期间保存地址。指针可以指向具有任何数据类型的变量,或者指向功能块实例。下面的 CheckPointer 函数一段中进一步描述了使用隐式指针监控函数的可能性。

指针声明语法

<identifier>: POINTER TO <data type>;

取消引用某个指针意味着获取在其指向的地址中当前存储的值。您可以通过在指针标识符后面添加内容操作符 ^(ASCII 脱字号或扬抑符号)来取消引用指针。请参阅以下示例中的 pt^

您可以使用 ADR address operator 来为指针分配变量地址。

注: 指向 I/O 输入的指针需要执行写访问。因此,在生成代码时,会触发编译器消息 '<pointer name >' is not a valid assignment target

示例:pwInput := ADR(wInput);

为了避免编译器检测到这样的错误,请将输入值 (wInput) 复制到支持写访问的变量。

示例

VAR
  pt:POINTER TO INT;  (* of pointer pt *)
var_int1:INT := 5;  (* declaration of variables var_int1 and var_int2 *)
  var_int2:INT;
END_VAR
pt := ADR(var_int1); (* address of var_int1 is assigned to pointer pt *)
var_int2:= pt^;      (* value 5 of var_int1 gets assigned to var_int2 via dereferencing of pointer pt; *)

在线模式下,您可以通过执行转到引用命令,从指针跳转到引用变量的声明位置。

函数指针

EcoStruxure Machine Expert 还支持函数指针。这些指针可以传递到外部库,但是在编程系统中,无法在应用程序中调用函数指针。用于注册回调函数(系统库函数)的运行时函数期望函数指针,并且根据请求注册的回调,将通过运行时系统来隐式调用各自函数(例如,在 STOP)。要启用此类系统调用(运行时系统),请设置函数对象的各自属性(默认情况下,在视图 > 属性... > 编译)下面。

您可以对函数名称、程序名称、功能块名称和方法名称使用 ADR 操作符。由于在在线修改后函数可能移动,因此结果不是函数地址,而是函数指针的地址。只要目标上存在该函数,此地址便有效。

执行在线更改命令可能更改地址内容。

 小心
指针无效
对地址使用指针并执行在线更改命令时,请检查指针的有效性。
不遵循上述说明可能导致人身伤害或设备损坏。

指针的索引访问

作为 IEC 61131-3 标准的扩展,允许对 POINTERSTRINGWSTRING 类型的变量进行索引访问 []

  • [i] 将返回基本数据类型。

  • 对指针的索引访问为算术:

    如果对指针类型的变量使用了索引访问,则偏移 pint[i] 等于 (pint + i * SIZEOF(base type))^。索引访问还将对指针执行隐式取消引用。结果类型是指针的基本类型。

    请注意 pint[7] does not equate to (pint + 7)^

  • 如果对 STRING 类型的变量使用了索引访问,则结果是位于偏移 index-expr 的字符。结果是 BYTE 类型。[i] 将字符串的第 i 个字符返回为 SINT (ASCII)。

  • 如果对 WSTRING 类型的变量使用了索引访问,则结果是位于偏移 index-expr 的字符。结果是 WORD 类型。[i] 将字符串的第 i 个字符返回为 INT (Unicode)。

注: 还可以使用引用。引用是与指针相对的一个概念,它会直接影响值。

指针相减

两个指针之间的差值结果是 DWORD 类型的值。

CheckPointer 功能

如要在运行期间监控指针访问,可以使用隐式监控函数 CheckPointer。如有需要,可以对其加以调整。要实现此目的,请向应用程序中添加对象用于隐式检查的 POU用于隐式检查的 POU。激活指针检查类别的相关复选框。

注: 您必须在机器试运行期间实现 CheckPointer 函数,以检查所传送的指针是否引用了有效的内存地址以及所引用的存储区的对齐是否符合指针所指向的变量的数据类型。

CheckPointer 以类似的方式监控 REFERENCE TO 类型的变量。

注: 对于 THIS 指针,不存在检查函数的隐式调用。

模板:

声明部分:

// Implicitly generated code : DO NOT EDIT
FUNCTION CheckPointer : POINTER TO BYTE
VAR_INPUT
ptToTest : POINTER TO BYTE;
iSize : DINT;
iGran : DINT;
bWrite: BOOL;
END_VAR

调用时,为函数提供了下列输入参数:

  • ptToTest:指针的目标地址

  • iSize:所引用变量的大小;iSize 的数据类型必须兼容整数,并且必须涵盖指针地址中存储的可能出现的最大数据。

  • iGran:访问的细粒度,即,所引用变量中使用的最大非结构化数据类型;iGran 的数据类型必须兼容整数

  • bWrite:访问类型(TRUE= 写访问,FALSE= 读访问);bWrite 的数据类型必须为 BOOL

PacDrive 控制器的 CheckPointer 函数实现

PacDrive 控制器 (PacDrive LMC Eco / PacDrive LMC Pro/Pro2) 的 CheckPointer 函数实现旨在生成系统运行时异常,以及在对齐的内存地址无效时,将调用栈写入到消息记录器中。

实现部分:

CheckPointer := ptToTest;
IF ptToTest = 0 THEN
        FC_DiagMsgWrite(4, 'CP = 0');
        FC_SysUserCallStack(0);
ELSE
        CheckPointer := ptToTest;
END_IF

Optimized 控制器的 CheckPointer 函数实现

Optimized 控制器(如 Modicon M241 Logic Controller)的 CheckPointer 函数实现用于返回所传送的指针。

实现部分(不完整):

// No standard way of implementation. Fill your own code here
CheckPointer := ptToTest;

如果检查结果为正,则将返回未修改的输入指针 (ptToTest)。