__NEW
Questo operatore non è specificato dallo standard IEC 61131-3.
L'operatore __NEW
alloca memoria dinamica per istanze di blocchi funzione, tipi di dati definiti dall'utente o matrici di tipi di dati standard. L'operatore restituisce un puntatore di tipo adatto per l'oggetto. Se l'operatore non è utilizzato in un'assegnazione, viene visualizzato un messaggio.
Attivare l'opzione vista ( ) per utilizzare l’operatore __NEW
. Consultare la Guida alla programmazione del controller specifico per vedere se le opzioni sono disponibili sul controller.
Se non è stato possibile allocare memoria, __NEW
restituirà 0.
Per annullare l'allocazione, usare __DELETE
.
<pointer name> := __NEW (<tipo>[,<dimensione>]);
L'operatore crea un nuovo oggetto del tipo specificato <type>
e restituisce un puntatore per questo <type>
. Dopo la creazione viene chiamata l'inizializzazione dell'oggetto. Se viene restituito 0, l'operazione non è stata eseguita correttamente.
POINTER TO BaseFB
. Ciò è necessario in quanto, se il blocco funzionale di base non implementa alcuna funzione FB_Exit
, a un successivo uso di __DELETE(pBaseFB)
, non viene chiamato alcun FB_Exit
.
Se <type>
è scalare, deve essere impostato anche l'operando opzionale <size>
e l'operatore crea un array di tipi scalari con la dimensione lunghezza.
pScalarType := __New(ScalarType, length);
Pertanto, solo i blocchi funzione delle librerie (dato che non possono essere modificati) e i blocchi funzione con l'attributo enable_dynamic_creation
sono ammessi per l'operatore __NEW
. Se un blocco funzionale cambia con questo flag ed è necessario il codice di copia, viene emesso un messaggio.
Per evitare che due task tentino di allocare memoria contemporaneamente viene utilizzato un semaforo (SysSemEnter
). Di conseguenza, l'uso ricorrente di __New
può produrre disturbi più intensi.
Esempio con un tipo scalare:
{attribute 'enable_dynamic_creation'}
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
Esempio con un blocco funzionale:
{attribute 'enable_dynamic_creation'}
FUNCTION_BLOCK FBDynamic
VAR_INPUT
in1, in2 : INT;
END_VAR
VAR_OUTPUT
out : INT;
END_VAR
VAR
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);
END_IF
IF (bDelete) THEN
__DELETE(pFB);
END_IF
Esempio con un 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