操作符是 IEC 61131-3 标准的延伸。
__NEW
运算符为实例化功能块、用户定义的数据类型或标准类型的数组保留动态内存。操作符会返回一个匹配的键入指针。
要求:在父应用程序的属性对话框中,在“Application Build Options” 选项卡上,选择“Use dynamic memory allocation” 选项。
语法
<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'}
来标记对象。作为库一部分的功能块则不需要。
如果在联机模式下更改了功能块的数据布局,则之后将无法执行联机更改登录。这是因为功能块实例的内存区域已失效。在功能块中添加新变量、删除现有变量或更改变量数据类型时,都会更改数据布局。
示例
数组 (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
数组 (BYTE):
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
操作符。