Calling TCL from C Link to heading
Starting with working example, we can see that Tcl_CreateInterp
and Tcl_Eval
are the only two Tcl calls.
#include <stdio.h>
#include <tcl.h>
main (int argc, char *argv[]) {
Tcl_Interp *myinterp;
char *action = "set a [expr 5 * 8]; puts $a";
int status;
printf ("Your Program will run ... \n");
myinterp = Tcl_CreateInterp();
status = Tcl_Eval(myinterp,action);
printf ("Your Program has completed\n");
}
And compilation command
gcc main.c -I /usr/include/tcl8.6 -ltcl
Docs says Tcl_CreateInterp
is
Tcl_CreateInterp creates a new interpreter structure and returns a token for it. The token is required in calls to most other Tcl procedures, such as Tcl_CreateCommand, Tcl_Eval
And Tcl_Eval
Tcl_Eval is similar to Tcl_EvalObjEx except that the script to be executed is supplied as a string instead of a value and no compilation occurs.
Calling C from TCL (TCL extension) Link to heading
On the other side, TCL provides an interface to call C from TCL same as built-in procs.
For this to work, we need to 2 functions:
- Registration called when shared object is loaded
- proc implementation
Docs describes Tcl_CreateObjCommand
Tcl_CreateObjCommand deletes any existing command name already associated with the interpreter (however see below for an > exception where the existing command is not deleted). It returns a token that may be used to refer to the command in subsequent > calls to Tcl_GetCommandName. If name contains any :: namespace qualifiers, then the command is added to the specified namespace; > otherwise the command is added to the global namespace. If Tcl_CreateObjCommand is called for an interpreter that is in the > process of being deleted, then it does not create a new command and it returns NULL. proc should have arguments and result that > match the type Tcl_ObjCmdProc:
typedef int Tcl_ObjCmdProc( ClientData ta, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
#include <stdio.h>
#include <tcl.h>
static int hello(ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
{
printf("Hello World\n");
return TCL_OK;
}
int Hello_Init(Tcl_Interp *interp)
{
Tcl_CreateObjCommand(interp, "hello", hello, NULL, NULL);
return TCL_OK;
}
gcc commands to compile shared object
gcc -c hello.c -I /usr/include/tcl8.6
gcc -shared -o hello.so hello.o -ltcl
Finally, we need to load the shared object with TCL load
.
load ./hello.so
hello
Side note, Docs mentions Hello_Init
has to be called SOMEHING_Init
for load command to execute it while loading the shared object. According to docs, SOMETHING
is package name .
C-TCL-C chaining Link to heading
for fun, I tried chaining C calling TCL and TCL calling C.
This is main.c (the main driver)
#include <stdio.h>
#include <tcl.h>
void main (int argc, char *argv[]) {
Tcl_Interp *myinterp;
char *action = "load ./hello.so;hello";
int status;
printf ("Your Program will run ... \n");
myinterp = Tcl_CreateInterp();
status = Tcl_Eval(myinterp,action);
printf ("Your Program has completed\n");
}
and hello.c same as before.