Posted to tcl by emiliano at Wed Apr 29 13:46:16 GMT 2009view pretty
here's the extension code (transform.c): 8<----------8<----------8<----------8<----------8<---------- /* * transform.c -- Quickly transform a list for graphing */ #include <tcl.h> /* * Transform_Cmd * this function implements the command and does the transform */ static int Transform_Cmd ( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[] ) { int index, length, result; double xoffset, xscale, yoffset, yscale, x, y; Tcl_Obj * xlistPtr, * ylistPtr; Tcl_Obj * newlist; if (objc != 6) { Tcl_WrongNumArgs(interp, 1, objv, "list xoffset xscale yoffsset yscale"); return TCL_ERROR; } /* The list should have an even number of elements */ result = Tcl_ListObjLength(interp, objv[1], &length); if (result == TCL_ERROR) { return TCL_ERROR; } if (length % 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list should have an even number of elements",-1)); return TCL_ERROR; } /* Now, the last four parameters need to be doubles */ if ( Tcl_GetDoubleFromObj(interp, objv[2], &xoffset) != TCL_OK || Tcl_GetDoubleFromObj(interp, objv[3], &xscale) != TCL_OK || Tcl_GetDoubleFromObj(interp, objv[4], &yoffset) != TCL_OK || Tcl_GetDoubleFromObj(interp, objv[5], &yscale) != TCL_OK ) { return TCL_ERROR; } result = TCL_OK; newlist = Tcl_NewListObj(0, NULL); Tcl_IncrRefCount(newlist); for ( index = 0; index < length ; index += 2) { result = Tcl_ListObjIndex(interp, objv[1], index, &xlistPtr); if (result == TCL_ERROR) break; result = Tcl_GetDoubleFromObj(interp, xlistPtr, &x); if (result == TCL_ERROR) break; result = Tcl_ListObjIndex(interp, objv[1], index+1, &ylistPtr); if (result == TCL_ERROR) break; result = Tcl_GetDoubleFromObj(interp, ylistPtr, &y); if (result == TCL_ERROR) break; Tcl_ListObjAppendElement( interp, newlist, Tcl_NewDoubleObj(xoffset + xscale * x)); Tcl_ListObjAppendElement( interp, newlist, Tcl_NewDoubleObj(yoffset + yscale * y)); } if (result == TCL_OK) { Tcl_SetObjResult (interp, newlist); } Tcl_DecrRefCount(newlist); return result; } /* * Transform_Init -- Called when Tcl loads the extension. */ int DLLEXPORT Transform_Init(Tcl_Interp *interp) { if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) { return TCL_ERROR; } if (Tcl_PkgProvide(interp, "Transform", "0.1") == TCL_ERROR) { return TCL_ERROR; } Tcl_CreateObjCommand(interp, "grafico::transforma_datos", Transform_Cmd, NULL, NULL); return TCL_OK; } 8<----------8<----------8<----------8<----------8<---------- here's the short Makefile 8<----------8<----------8<----------8<----------8<---------- TCL_INCLUDES= -I/usr/local/include TCL_LIBSPEC= -DUSE_TCL_STUBS -L/usr/local/lib -ltclstub8.6 libtransform.so: transform.c rm -f libtransform.so gcc -fPIC -shared -o libtransform.so ${TCL_INCLUDES} ${TCL_LIBSPEC} transform.c 8<----------8<----------8<----------8<----------8<---------- after compiling the extension, this is what happens: emiliano@merlot:~/indicador$ tclsh8.6 % load ./libtransform.so couldn't load file "./libtransform.so": ./libtransform.so: undefined symbol: tclStubsPtr %