As far as I know, there is no way to detect what is the datatype of the pointer, as it's just a memory address. You should provide the size of the pointer target as other parameter, as you said. Just add a check that pointer is not zero and size is not zero to prevent (some) problems.
Solutions for other environments:
For TwinCAT 3 it would be possible to create one-input solution by using T_Arg
and helpers suchs as F_INT
but I think Codesys 2 doesn't have them (confirmation anyone?). In that solution you would have to change the function call anyways so that pointer wouldn't be an input.
In that solution you could create a function with input of T_Arg
. And then call it by using a helper function for each datatype. From T_Arg
is possible to acquire data type, size and data location.
FUNCTION_BLOCK FB_Test
VAR_INPUT
Test : T_arg;
END_VAR
Test.eType; //Data type
Test.cbLen; //Variable data length in bytes
Test.pData; //Pointer to data
And to call it:
test is an instance of FB_Test
//INT for example
//Now the cblen = 2
test(
Test := F_INT(PointerToInt^)
);
//REAL for example
//Now the cbLen = 4
test(
Test := F_REAL(PointerToReal^)
);
This is perhaps a little offtopic so sorry about that, hope it helps somebody. Still hoping that somebody would know a better solution.
EDIT
Actually found other great solution, but I think it is also only for TwinCAT 3. Just wanted to post it here too.
By using ANY
data type, it is possible to give anything as parameter and get it's size. The difference is that it won't accept POINTER
as input.
FUNCTION_BLOCK FB_Test2
VAR_INPUT
Test : ANY;
END_VAR
VAR_OUTPUT
Size : DINT;
END_VAR
//diSize contains size of the input data type
size := Test.diSize;
Usage:
//test2 is an instance of FB_Test2
//Output "Size" is 4, as this is a REAL
test2(
Test := PointerToReal^
);