Posted to tcl by emiliano at Wed Apr 29 13:46:16 GMT 2009view raw
- 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
- %