0
votes

I am writing a c++ code to eval a tcl proc. i have two TCL files. any of two can have the tcl proc say file1.tcl has tcl proc mytest. file2.tcl is sourcing file1.tcl so if i do [info procs mytest] in file2.tcl , i am able to get the tcl proc name mytest. But in the c++ when I try to eval the proc, it says invalid command mytest. However if I write proc mytest in file2.tcl ,it works.

file1.tcl is user input and file2.tcl is default input. only in case proc is missing in file1.tcl, I will call file2.tcl proc. Please suggest how can i get it work.

Thanks Ruchi

1
If you haven't done so yet, I suggest you to please read the Stack Overflow question checklist.Some programmer dude

1 Answers

1
votes

Your question isn't entirely clear, but it seems that you have two files, one of which you control (and which provides default implementations of some Tcl commands?) and the other of which is controlled by your users (so they can override things?). You then want to load these into a Tcl interpreter context so that you can call things from C++? I'll assume that's what's going on.

Firstly, from the Tcl perspective you do this by getting the context (the Tcl_Interp*) to source the file with the default implementations. (There are other ways to do it, but that's definitely easiest.) Only after that is done would you source the file with the user definitions, and you would only do the call in to kick things off after everything has finished sourcing in correctly. So that's what we're aiming for.

From C++, the main things to note are that Tcl_EvalFile() is the equivalent of source in Tcl (just as Tcl_Eval() is the equivalent of eval), and that you have to take care with checking for errors; Tcl doesn't map its exception system to C++ exceptions at all, so check those return codes.

Tcl_Interp *interp = Tcl_CreateInterp();

if (Tcl_EvalFile(interp, "file2.tcl") != TCL_OK) {
    const char *errorMessage = Tcl_GetString(Tcl_GetObjResult(interp));
    // Deal with error
    cerr << "Problem in library: " << errorMessage << "\n";
    exit(1);
}

if (Tcl_EvalFile(interp, "file1.tcl") != TCL_OK) {
    const char *errorMessage = Tcl_GetString(Tcl_GetObjResult(interp));
    cerr << "Problem in user code: " << errorMessage << "\n";
    exit(1);
}

// Everything ready
if (Tcl_Eval(interp, "[the_party get] start") != TCL_OK) {
    // Something still went wrong...