Skip to main content

运营商:__NEW

运算符是 IEC 61131-3 标准的扩展。

__NEW 运算符保留动态内存以实例化功能块、用户定义的数据类型或标准类型的数组。运算符返回一个匹配的类型指针。

要求:在父应用程序的属性对话框中,在 应用程序构建选项 制表符 使用动态内存分配 选项被选中。

句法

<pointer name> := __NEW( <type> ( , <size> )? );
__DELETE( <pointer name> );

<type> : <function block> | <data unit type> | <standard data type>

运算符生成类型的实例 <type> 并返回一个指向该实例的指针。然后调用实例的初始化。如果 <type> 是标量标准数据类型,然后是可选操作数 <size> 也被评估。然后操作符生成一个类型的数组 <standard data type> 和大小 <size>.如果分配内存的尝试失败,则 __NEW 返回值 0.

在赋值中使用运算符 ":="; 否则会显示错误消息。

一个功能块或用户定义的数据类型,其实例是动态创建的 __NEW 使用固定的内存区域。这里需要你用 pragma 标记对象 {attribute 'enable_dynamic_creation'}.作为库一部分的功能块不需要它。

提示

如果在在线模式下更改功能块的数据布局,则无法在之后执行在线更改的登录。这是因为功能块实例的内存区域已经失效。当您向功能块添加新变量、删除现有变量或更改变量的数据类型时,您会更改数据布局。

150. 例子

大批 (DWORD)

PROGRAM PLC_PRG
VAR
        pdwScalar : POINTER TO DWORD; //Typed pointer
        xInit : BOOL := TRUE;
        xDelete : BOOL;
END_VAR

IF (xInit) THEN
        pdwScalar := __NEW(DWORD, 16); // Allocates memory (16 dwords) and assigns them to pointer pdwScalar
END_IF
IF (xDelete) THEN
        __DELETE(pdwScalar); // Frees memory of pointer
END_IF

功能块

{attribute 'enable_dynamic_creation'}
FUNCTION_BLOCK FBComputeGamma
VAR_INPUT
        iAlpha : INT;
        iBeta : INT;
END_VAR
VAR_OUTPUT
        iGamma : INT;
END_VAR
VAR
END_VAR

iGamma := iAlpha + iBeta;

PROGRAM PLC_PRG
VAR
        pComputeGamma : POINTER TO FBComputeGamma;      // Typed pointer
        xInit : BOOL := TRUE;
        xDelete : BOOL;
        iResult : INT;
END_VAR

IF (xInit) THEN
        pComputeGamma := __NEW(FBComputeGamma); // Allocates memory
        xInit := FALSE;
END_IF
pComputeGamma^.iAlpha := (pComputeGamma^.iAlpha + 1)MOD 100; // Sets first input of pComputeGamma
pComputeGamma^.iBeta := 10; // Sets second input of pComputeGamma
pComputeGamma^(); // Calls the FB pComputeGamma is pointing to
iResult := pComputeGamma^.iGamma; // Reads output of pComputeGamma
IF (xDelete) THEN
    __DELETE(pComputeGamma); // Frees memory
END_IF

用户定义的数据类型 (DUT)

{attribute 'enable_dynamic_creation'}
TYPE ABCDATA :
STRUCT
             iA, iB, iC, iD : INT;
END_STRUCT
END_TYPE

PROGRAM PLC_PRG
VAR
        pABCData : POINTER TO ABCDATA; // Typed pointer
        xInit : BOOL := TRUE;
        xDelete : BOOL;
END_VAR

IF (xInit) THEN
    pABCData := __NEW(ABCDATA); // Allocates memory
    xInit := FALSE;
END_IF
IF (xDelete) THEN
    __DELETE(pABCData); // Frees memory
END_IF

数组(字节)

PROGRAM PLC_PRG
VAR
        pbDataAlpha : POINTER TO BYTE;
        pbDataBeta : POINTER TO BYTE;
        xInit : BOOL := TRUE;
        xDelete : BOOL;
        usiCnt : USINT;
        bTestC: BYTE;
END_VAR

IF (xInit) THEN
        pbDataAlpha := __NEW(BYTE, 16); // Allocates 16 bytes for pbDataAlpha
        pbDataBeta := __NEW(BYTE);  // Allocates memory for pbDataBeta
        xInit := FALSE;

        FOR usiCnt := 0 TO 15 DO
                pbDataAlpha[usiCnt] := usiCnt; // Writes to new array
        END_FOR
        pbDataBeta^:= 16#FF; // Writes to new data
END_IF

bTestC := pbDataAlpha[12];  // Reads new array by index access

IF (xDelete) THEN // Frees memory
        __DELETE(pbDataAlpha);
        __DELETE(pbDataBeta);
END_IF


重要

我们不建议同时执行两个调用 __NEW 操作员。您可以使用信号量 (SysSemEnter) 或类似的技术来防止同时调用 __NEW.然而,这会导致更高的抖动时 __NEW 被广泛应用。

我们建议您致电 __NEW 仅在一项任务中的操作员。