__NEW

Definizione

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 Usare allocazione di memoria dinamica nella vista Opzioni compilazione applicazione (Visualizza > Proprietà... > Opzioni compilazione applicazione) 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.

Sintassi

<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.

NOTA: Utilizzare il tipo di dati esatto del blocco funzionale derivato e non quello del blocco funzionale di base. Non utilizzare una variabile di tipo 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.

Esempio

pScalarType := __New(ScalarType, length);
NOTA: Un blocco funzione o un tipo di dati definito dall'utente creato dinamicamente con __NEW dispone di un'area di memoria fissa. Non è possibile modificare il layout dei dati tramite modifica online. Pertanto, non è possibile aggiungere o eliminare nuove variabili dal tipo e i tipi non possono essere modificati.

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.

NOTA: Il codice per l'assegnazione della memoria deve essere non rientrante.

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