**TIP content** ***Abstract*** This TIP proposes adding a command, '''Tcl_LinkArray''', to allow linking of C variables to Tcl lists. It also adds more types of linked variable. ***Rationale*** The current C-API allows one to only link single variables. The proposed Tcl_LinkArray function allows the linking of C-arrays to Tcl list variables. If the given size value is 1 then it works like the existing Tcl_LinkVar function. The automatic creation of needed space when no address value is provided could be used for testing scenarios. The new link types also allow one to link from strings and binary arrays to fixed memory locations. The use of arrays with a given size > 1 allows a safe and simple C-Tcl connection. Array overwrites create errors. ***Specification*** This document proposes the following changes to the Tcl core: ****New C API**** Add a new public `Tcl_LinkArray` function to provide links of single variable and array variables. The new function would have the same parameters as the `Tcl_LinkVar` function, plus an additional int size. If the given size is 1, then we have the same functionality as before. With size > 1, the linked Tcl variable is a list variable. If the given address is NULL then the function allocates the necessary space on the C side itself. `int Tcl_LinkArray(Tcl_Interp *interp, const char *varName, char *addr, int type, int size)` The `Tcl_LinkVar` function will remain for compatibility. The function will call the new function with `size=1`. The following link types will be defined in tcl.h: ====== #define TCL_LINK_INT 1 /* 32bit int -> int */ #define TCL_LINK_DOUBLE 2 /* 64bit double -> double */ #define TCL_LINK_BOOLEAN 3 /* tcl boolean -> int */ #define TCL_LINK_STRING 4 /* 8bit chars -> ckalloc'd string */ #define TCL_LINK_WIDE_INT 5 /* 64bit int -> Tcl_WideInt */ #define TCL_LINK_CHAR 6 /* 8bit int -> char */ #define TCL_LINK_UCHAR 7 /* 8bit uint -> unsigned char */ #define TCL_LINK_SHORT 8 /* 16bit int -> short */ #define TCL_LINK_USHORT 9 /* 16bit int -> unsigned short */ #define TCL_LINK_UINT 10 /* 32bit uint -> int */ #define TCL_LINK_LONG 11 /* long -> long */ #define TCL_LINK_ULONG 12 /* unsigned long -> unsigned long */ #define TCL_LINK_FLOAT 13 /* 32bit float -> double */ #define TCL_LINK_WIDE_UINT 14 /* 64bit uint -> wide TODO bignum */ #define TCL_LINK_CHARS 15 /* 8bit chars -> null terminated string last char will always set to \0 */ #define TCL_LINK_COMPLEX32 16 /* 32bit complex -> double+double */ #define TCL_LINK_COMPLEX64 17 /* 64bit complex -> double+double */ #define TCL_LINK_BINARY 18 /* fixed size binary byte array */ #define TCL_LINK_HEX8 19 /* 8bit uint -> string, 2 hex chars */ #define TCL_LINK_HEX16 20 /* 16bit uint -> string, 4 hex chars */ #define TCL_LINK_HEX32 21 /* 32bit uint -> string, 8 hex chars */ #define TCL_LINK_HEX64 22 /* 64bit uint -> string, 16 hex chars */ #define TCL_LINK_BITARRAY8 23 /* 8bit uint -> string, 8 chars 0|1 */ #define TCL_LINK_BITARRAY16 24 /* 16bit uint -> string, 16 chars 0|1 */ #define TCL_LINK_BITARRAY32 25 /* 32bit uint -> string, 32 chars 0|1 */ #define TCL_LINK_BITARRAY64 26 /* 64bit uint -> string, 64 chars 0|1 */ #define TCL_LINK_BOOL8 27 /* 8bit uint -> int (0|1) */ #define TCL_LINK_BOOL16 28 /* 16bit uint -> int (0|1) */ #define TCL_LINK_BOOL32 29 /* 32bit uint -> int (0|1) */ #define TCL_LINK_BOOL64 30 /* 64bit uint -> int (0|1) */ #define TCL_LINK_BIT8 31 /* bit in 8bit uint -> int (0|1) */ #define TCL_LINK_BIT16 32 /* bit in 16bit uint -> int (0|1) */ #define TCL_LINK_BIT32 33 /* bit in 32bit uint -> int (0|1) */ #define TCL_LINK_BIT64 34 /* bit in 64bit uint -> int (0|1) */ #define TCL_LINK_S5FLOAT 35 /* Siemens S5 32bit uint -> double */ #define TCL_LINK_S5TIME 36 /* Siemens S5 16bit uint -> double */ ====== `TCL_LINK_CHARS` The address of the C variable is used as a char *. The address remains always the same (different to TCL_LINK_STRING) and contains a \0 terminated string. The \0 counts towards the given size. The Tcl variable is used as a string and can contain up to size -1 characters. `TCL_LINK_BINARY` The address of the C variable is used as a unsigned char *. The address remains always the same. Read and write operations must always contain the full sized binary string. ***Testing*** The tests in the tcl test suite for the `Tcl_LinkVar` function are working. Additional tests for the `Tcl_LinkArray` function are needed. To support this a `testlinkarray` command is included in the tclTest.c file. The implementing C-function `TestlinkarrayCmd` can be used as a starting point for extensions who will use the new functionality from tcl. The function is not exposed as normal tcl command because wrong usage can lead to segmenation faults. **Reference Implementation** To test the new functionality get 20170307_tip312.tgz from https://sourceforge.net/projects/kbskit/files/ Apply the patch files tcl.h.patch and tclTest.c.patch. And replace tclLink.c with the new one. To use the new `Tcl_LinkArray` from outside you need to apply the tcl.decl.patch file and do a ====== make genstubs ====== <>TIP