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
%