This operator is not prescribed by the IEC 61131-3 standard.
The operator __NEW allocates memory for function block instances or arrays of standard data types. The operator returns a suitably typed pointer to the object. If the operator is not used within an assignment, a message is displayed.
Activate the option Use dynamic memory allocation in the Application build options view (View > Properties... > Application build options) to use the __NEW operator. Consult the Programming Guide specific to your controller for whether the options are available on your controller.
If no memory could be allocated, by __NEW will return 0.
For deallocating, use __DELETE.
__NEW (<type>, [<size>]
The operator creates a new object of the specified type <type> and returns a pointer to that <type>. The initialization of the object is called after creation. If 0 is returned, the operation has not been completed successfully.
NOTE: Use the exact data type of the derived function block and not that of the base function block. Do not use a variable of type POINTER TO BaseFB. This is necessary because if the base function block implements no FB_Exit function, then at the later usage of __DELETE(pBaseFB), no FB_Exit is called.
If <type> is scalar, the optional operand <length> has to be set additionally and the operator creates an array of scalar types with the size length.
pScalarType := __New(ScalarType, length);
NOTE: A function block created with __NEW has a fixed memory area. The data layout cannot be modified by an online change. Therefore, new variables cannot be added or deleted, and types cannot be modified.
Therefore, only function blocks out of libraries (because they cannot change) and function blocks with attribute enable_dynamic_creation are allowed for the __NEW operator. If a function block changes with this flag so that copy code will be necessary, a message is produced.
NOTE: The code for memory allocation needs to be non-re-entrant.
A semaphore (SysSemEnter) is used to avoid 2 tasks try to allocate memory at the same time. Thus, extensive usage of __New may produce higher jitter.
Example with a scalar type:
TYPE DUT :
STRUCT
a,b,c,d,e,f : INT;
END_STRUCT
END_TYPE
PROGRAM PLC_PRG
VAR
pDut : POINTER TO DUT;
bInit: BOOL := TRUE;
bDelete: BOOL;
END_VAR
IF (bInit) THEN
pDut := __NEW(DUT);
bInit := FALSE;
END_IF
IF (bDelete) THEN
__DELETE(pDut);
END_IF
Example with a function block:
{attribute 'enable_dynamic_creation'}
FUNCTION_BLOCK FBDynamic
VAR_INPUT
in1, in2 : INT;
END_VAR
VAR_OUTPUT
out : INT;
END_VAR
VAR
test1 : INT := 1234;
_inc : INT := 0;
_dut : POINTER TO DUT;
END_VAR
out := in1 + in2;
PROGRAM_PLC_PRG
VAR
pFB : POINTER TO FBDynamic;
loc : INT;
bInit: BOOL := TRUE;
bDelete: BOOL;
END_VAR
IF (bInit) THEN
pFB := __NEW(FBDynamic);
bInit := FALSE;
END_IF
IF (pFB <> 0) THEN
pFB^(in1 := 1, in2 := loc, out => loc);
pFB^.INC();
END_IF
IF (bDelete) THEN
__DELETE(pFB);
END_IF
Example with an array:
PLC_PRG(PRG)
VAR
bInit: BOOL := TRUE;
bDelete: BOOL;
pArrayBytes : POINTER TO BYTE;
test: INT;
parr : POINTER TO BYTE;
END_VAR
IF (bInit) THEN
pArrayBytes := __NEW(BYTE, 25);
bInit := FALSE;
END_IF
IF (pArrayBytes <> 0) THEN
pArrayBytes[24] := 125;
test := pArrayBytes[24];
END_IF
IF (bDelete) THEN
__DELETE(pArrayBytes);
END_IF