int Tcl_and_c_Adder(ClientData clientData,
Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]);
int Tcl_and_c_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "fooadder", Tcl_and_c_Adder,
NULL, NULL);
Tcl_PkgProvide(interp, "foo", "1.1");
return TCL_OK;
}
Tcl_CreateObjCommand(interp, "fooadder", Tcl_and_c_Adder,
NULL, NULL);
This is the connection from the C side to the Ttcl side. The new command will be named fooadder in tcl and is implemented in Tcl_and_Adder. the next parameter can be used to hand over well any kind of data, eg a tcl hash table and the last parameter is a delete function for cleaning up data held in ClienData, if they are e.g heap allocated. We do not need that.
int Tcl_and_c_Adder(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]) {
int i_result = 0;
Tcl_Obj *result;
int ct = objc-1;
int i;
int i_rval;
while (ct > 0){
i_rval = Tcl_GetIntFromObj(interp, objv[ct], &i);
if (TCL_OK != i_rval){
return TCL_ERROR;
}
i_result += i;
ct--;
}
result = Tcl_GetObjResult(interp);
Tcl_SetIntObj(result, i_result);
return TCL_OK;
}
result = Tcl_GetObjResult(interp);
Tcl_SetIntObj(result, i_result);
echo $auto_path
/usr/share/tcltk/tcl8.5 /usr/lib /usr/local/lib/tcltk /usr/local/share/tcltk /usr/lib/tcltk /usr/share/tcltk /home/frido/programming/tcl/tcl_and_c/dist/Debug/GNU-Linux-x86
now it's easy to load in tclsh:
package require foo
1.1
fooadder 1 2 3
6
#include <tcl.h>
int Tcl_and_c_Adder(ClientData clientData,
Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]);
int Tcl_and_c_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "fooadder", Tcl_and_c_Adder,
NULL, NULL);
Tcl_PkgProvide(interp, "foo", "1.1");
return TCL_OK;
}
int Tcl_and_c_Adder(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[]) {
int i_result = 0;
Tcl_Obj *result;
int ct = objc-1;
int i;
int i_rval;
while (ct > 0){
i_rval = Tcl_GetIntFromObj(interp, objv[ct], &i);
if (TCL_OK != i_rval){
return TCL_ERROR;
}
i_result += i;
ct--;
}
result = Tcl_GetObjResult(interp);
Tcl_SetIntObj(result, i_result);
return TCL_OK;
}
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (0)