I'm trying to build a function that sums a single dimension array of any type in TwinCAT.
I'm relatively inexperienced with pointers so the answer may be obvious, but I could not find any solutions. I read through all these and they helped a bit.
T_ARG Convert Byte arrays The Wonders of ANY
My conceptual code works for an INT array, but I realized I would have to write a FOR loop for each datatype to make it work and that seems wrong. I also wanted to avoid having a CASE in a FOR loop as that seemed inefficient.
Is it possible to have a pointer (of unset type) to a pointer (of a specific type)? It looks possible in C, but not sure about IEC-61131.
FUNCTION fn_SumArray : DINT
VAR_INPUT
inArr : ANY;
inElem : ANY;
END_VAR
VAR
i : DINT := 0;
stepsize : DINT :=1;
pLREAL : POINTER TO LREAL; //64 bit
pREAL : POINTER TO REAL; //32 bit
pBYTE : POINTER TO BYTE; //8 bit
pWORD : POINTER TO WORD; //16 bit
pDWORD : POINTER TO DWORD; //32 bit
pLWORD : POINTER TO LWORD; //64 bit
pSINT : POINTER TO SINT; //8 bit
pUSINT : POINTER TO USINT; //8 bit
pINT : POINTER TO INT; //16 bit
pUINT : POINTER TO UINT; //16 bit
pDINT : POINTER TO DINT; //32 bit
pUDINT : POINTER TO UDINT; //32 bit
pLINT : POINTER TO LINT; //64 bit
pULINT : POINTER TO ULINT; //64 bit
END_VAR
--------------------------------------------------
CASE inElem.TypeClass OF
__SYSTEM.TYPE_CLASS.TYPE_LREAL:
stepsize := 8;
//set generic pointer here
__SYSTEM.TYPE_CLASS.TYPE_INT:
stepsize := 2;
//set generic pointer here
ELSE
fn_SumArray :=0;
END_CASE;
FOR i := 0 TO inArr.diSize-1 BY stepsize DO
genericPointer:= ADR(inarr.pValue[i]);
fn_SumArray := fn_SumArray +genericPointer^;
END_FOR;
As far as I know, you'll have to repeat the code for all types you want to cover. CODESYS doesn't have true generic programming, so it is what it is:
The result of the program above:
If writing the same code for every type is too tedious, you can always use a script to automate this:
Just run the above script with python 3.x and you'll get the case statements code for the types listed in the script.