Reputation: 31
I am learning how to extend TCL with C++ and when I came to create new commands with the tcl.h library i found following example, it implements two new commands "Hola" and "Media". The first just print Hola Mundo (spanish for Hello Word) on the screen the second calculate the average of a set of numbers:
#include <stdio.h>
#include <tcl.h>
#include <tk.h>
/* Functions prototypes: */
int Tcl_AppInit(Tcl_Interp *interprete);
int hola (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[]);
int media (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[]);
void main (int argc,char *argv[])
{
Tk_Main(argc,argv,Tcl_AppInit);
}
/* Tk_Main creates interprete before calling Tcl_AppInit and then passing it as parameter */
int Tcl_AppInit(Tcl_Interp *interprete)
{
/*Intialazing Tcl:*/
if(Tcl_Init(interprete)==TCL_ERROR)
{
fprintf(stderr,"Error en la inicialización de Tcl.\n");
return TCL_ERROR;
}
/*Initialaizing Tk: */
if(Tk_Init(interprete)==TCL_ERROR)
{
fprintf(stderr,"Error en la inicialización de Tk.\n");
return TCL_ERROR;
}
/* New commands definitions: */
Tcl_CreateCommand(interprete,"hola",hola,(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interprete,"media",media,(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
return TCL_OK;
}
/* command implementation */
int hola (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[])
{
printf("\n\n¡Hola Mundo!!!\n\n");
return TCL_OK;
}
int media (ClientData clientdata,Tcl_Interp *interprete,int argc,char *argv[])
{
int elementos;
double numero;
double suma;
int i;
char **valores;
char resultado[20];
/* Take data list in argv[1] and use single components: */
Tcl_SplitList(interprete,argv[1],&elementos,&valores);
for(suma=0,i=0;i<elementos;i++)
{
if(Tcl_GetDouble(interprete,valores[i],&numero)==TCL_ERROR)
{
Tcl_SetResult(interprete,"Error en los parámetros",TCL_STATIC);
return TCL_ERROR;
}
suma+=numero;
}
sprintf(resultado,"%f",suma/elementos);
Tcl_SetResult(interprete,resultado,TCL_VOLATILE);
return TCL_OK;
}
The example seems old for me and from an Borland programer (because of the Void Main). When I tried to compile I got two errors on the new command definitions.
/* New commands definitions: */
Tcl_CreateCommand(interprete,"hola",hola,(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interprete,"media",media,(ClientData)NULL,
(Tcl_CmdDeleteProc *)NULL);
I get errors on
(ClientData)NULL
and
(Tcl_CmdDeleteProc *)NULL
After reading the Tcl manual I managed to change:
(ClientData)NULL to ClientData(NULL)
and it solved the first error but the second keep on giving error.
The errors:
For
(Tcl_CmdDeleteProc *)NULL --> not valid type conversion -fpermissive
For
Tcl_CmdDeleteProc *(NULL) --> needed primary expresion before token
For just typing NULL
NULL --> not valid type conversion
My question are: Am i writting it wrong? do I have to define Tcl_CmdDeleteProc s type?
I am compiling without flags, just "g++ -Wall name.cc -o name.o"
Upvotes: 1
Views: 164
Reputation: 137627
First off, Tcl_CmdDeleteProc
is a typedef for a function type. Function types have somewhat restrictive rules about what you can do with them.
The code:
Tcl_CmdDeleteProc *(NULL)
is completely wrong, as it is just a parse error. The code:
(Tcl_CmdDeleteProc *)NULL
is correct, but it's a C-style explicit cast and your compiler is set to complain about those without the -fpermissive
flag set. For C++, you probably want a static cast:
static_cast<Tcl_CmdDeleteProc *>(nullptr)
(If you're using an older C++, use NULL
instead of nullptr
.)
Upvotes: 1