Este operador no está preestablecido por el estándar IEC 61131-3.
El operador __NEW asigna memoria para las instancias de los bloques de funciones o para las matrices de tipos de datos estándar. El operador devuelve un puntero adecuadamente escrito al objeto. Si el operador no se utiliza en una asignación, se mostrará un mensaje.
Active la opción Utilizar asignación dinámica de memoria en la vista Opciones de creación de aplicaciones (Ver > Propiedades... > Opciones de creación de aplicaciones) para utilizar el operador __NEW. Consulte la guía de programación específica de su controlador para saber si su controlador dispone de estas opciones.
Si no se ha podido asignar memoria, __NEW devolverá 0.
Utilice __DELETE para anular una asignación.
__NEW (<tipo>, [<tamaño>]
El operador crea un nuevo objeto del tipo especificado <type> y devuelve un puntero a dicho <type>. Se llama a la inicialización del objeto después de su creación. Si el retorno es 0 la operación no se habrá completado satisfactoriamente.
NOTA: Utilice el tipo de datos exacto del bloque de funciones derivado y no el del bloque de funciones de base. No utilice una variable de tipo POINTER TO BaseFB. Esto es necesario porque, si el bloque de funciones de base no implementa ninguna función FB_Exit, cuando más adelante se utilice __DELETE(pBaseFB), no se llamará a ningún FB_Exit.
Si <type> es escalar, deberá establecerse además el operando opcional <length> y el operador creará una matriz de tipos escalares con esa longitud.
pScalarType := __New(ScalarType, length);
NOTA: Un bloque de funciones creado con __NEW cuenta con un área de memoria fija. El diseño de datos no puede modificarse mediante un cambio en línea. Así pues, las nuevas variables no pueden añadirse ni eliminarse, y los tipos no pueden modificarse.
Por consiguiente, solamente se permiten los bloques de funciones fuera de bibliotecas (debido a que no pueden cambiar) y los bloques de funciones con el atributo enable_dynamic_creation para el operador __NEW. Si un bloque de funciones cambia con este indicador de manera que se necesite hacer una copia del código, aparecerá un mensaje.
NOTA: El código para la asignación de memoria no puede ser reentrante.
Se utiliza un semáforo (SysSemEnter) para evitar que dos tareas traten de asignar memoria al mismo tiempo. En consecuencia, un uso excesivo de __New puede producir una mayor inestabilidad.
Ejemplo con un tipo escalar:
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
Ejemplo con un bloque de funciones:
{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
Ejemplo con una matriz:
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