// Define a command function in C style
int aCommand( ClientData data, Tcl_Interp* interp,
int args, char* argv[]) {
some_type* x = (some_type*) data; // conversion by cast
// some processing
}
// Declare the function aCommand as a Tcl command
// for example in the main function
some_type* user = new some_type(); // to create the client data
Tcl_CreateCommand( interp, "aco", aCommand, (ClientData) user );
slide: Command function in C style
Creating a command is done with reference
to an interpreter, which accounts for the
first argument of Tcl_CreateCommand.
The name of the command (aco in this case), as may be used
in a Tcl script is given as a second argument,
and the C style function defining the command as a third argument.
Finally, the address
of a structure containing client data (user in this case)
is passed as the fourth parameter.
When the function aCommand is invoked
as the result of executing the Tcl command aco,
the client data stored at
declaration time is passed as the first
argument to the function.
Since the type ClientData is actually defined
to be void*, the function must first
cast the client data argument to an appropriate
type as indicated above.
Clearly, casting is error-prone.
Another problem with command functions
as used in the Tcl C API is that
permanent data are possible only
in the form of client data,
global variables or static local
variables.
Both client data and global variables
are unsafe by being too visible
and static local data are simply inelegant.
The hush library has been developed
to offer a type-secure solution
to the problem of connecting C++ code
with Tcl,
and to allow for a safe way of maintaining
a (dynamically changing) state.
In hush the preferred way is to employ handler objects.
The obvious solution of associating class member functions
with Tcl commands does not work since pointers to
member functions are different from pointers to ordinary
C style functions.
intro
Tcl/Tk
programs
handler actions to events
widgets
graphics
appendix