__NEW

Definición

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.

Sintaxis

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

Ejemplo

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