[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Denemo-devel] Embedding a script interpreter in a C program
From: |
Richard Shann |
Subject: |
[Denemo-devel] Embedding a script interpreter in a C program |
Date: |
Thu, 14 Aug 2008 11:53:13 +0100 |
Jeremiah,
I've have been playing around with the linking side of scripting. I have
got a tcl interpreter to fire up Denemo, but as Denemo never returns,
this is not what we want.
This seems to be a poorly documented area: we want to embed a Tcl
interpreter in our C program, not extend a Tcl interpreter with Denemo
functions.
I've found the stuff below where people are discussing this
http://wiki.tcl.tk/2074
I append the relevant bit, as there is a lot of discussion about how
confusing the earlier bit of this page is.
I'll also send you the bits I have used to hack a Tcl module that runs
Denemo, in case it may help you, but I'll put it in a separate email to
avoid confusion
Richard
stuff from the wiki.tc.tk
...
At some point in our application, we have to start up a Tcl interpreter,
and register our wrapper function with the interpreter. This is usually
done with a function called Tcl_AppInit(). Once this initialization is
complete, your application can execute scripts from strings or files by
calling Tcl_Eval() or Tcl_EvalFile().
int Tcl_AppInit(Tcl_Interp *interp){
if (Tcl_Init(interp) == TCL_ERROR)
return TCL_ERROR;
/* Now initialize our functions */
Tcl_CreateCommand(interp, "square", _wrap_square, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
Call this initialization function somewhere in your main line. First
create an interpreter, then call Tcl_AppInit(). You could do this all in
one fell swoop, but the Tcl_AppInit() format is standard, and supports
creating extended interpreter shells - where your application actually
becomes a Tcl interpreter, which is Extremely Cool!(tm)
Tcl_Interp *interp;
interp = Tcl_CreateInterp();
Tcl_AppInit(interp);
The more modern approach to integrating Tcl applications depends on the
object interface supported in Tcl versions 8.0 and higher. The object
model supports the on-the-fly bytecode compiler, and is very efficient
for integrating C code. It is not necessary to shimmer values back and
forth to strings. Unfortunately, the object interface is a little more
complex, with special functions to convert from Tcl_Objs to basic types.
You should also do a little more careful parsing of arguments, and even
generate error messages if the Tcl command is malformed. Again, SWIG is
a great tool that can generate all this for you. But you can still do it
yourself. The new object interface function might look like this:
static int _wrap_square(ClientData clientData, Tcl_Interp *interp, int
objc, Tcl_Obj *CONST objv[]) {
int _result;
int _arg0;
Tcl_Obj * tcl_result;
int tempint;
clientData = clientData; objv = objv;
tcl_result = Tcl_GetObjResult(interp);
if ((objc < 2) || (objc > 2)) {
Tcl_SetStringObj(tcl_result,"Wrong # args. square i ",-1);
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp,objv[1],&tempint) == TCL_ERROR) return
TCL_ERROR;
_arg0 = (int ) tempint;
_result = (int )square(_arg0);
tcl_result = Tcl_GetObjResult(interp);
Tcl_SetIntObj(tcl_result,(long) _result);
return TCL_OK;
}
And, you would, of course, register this new command as an object
command. The rest of the initialization remains the same
Tcl_CreateObjCommand(interp, SWIG_prefix "square", _wrap_square,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Denemo-devel] Embedding a script interpreter in a C program,
Richard Shann <=