I'm trying to run a tcl script from some specific path on my PC from a C++ program. Unfortunately, I do not have any idea how to do so. Please advise how I can execute a tcl script from a C++ program. An example would be appreciated. For now, I have tried using the Tcl_Eval
command.

- 3,291
- 12
- 18

- 25
- 1
- 5
-
1Hello, your question is a bit broad and it is hard to know what you have tried? I would help if you could show us some (working) code, with an explanation of how it does not achieve what you want. – BobMorane May 24 '20 at 13:56
-
For example, it would be helpful to know if you are trying to fork a new process and run the script in the new process or if you want the script to run within the existing C++ program. – andy mango May 24 '20 at 16:10
-
Hi, I'm trying to run CPP script, at some point in the run, i want that the CPP test call a tcl script for run in, I have try this one - (Tcl_EvalFile(pInterp, "tclsh {\"C:/Users/avi/Desktop/Temp/test.tcl"}")); were not working for me. in addition, invoke a tcl shell and send a command that run the tcl scripts could be a good solution for me. thanks – user12755014 May 24 '20 at 16:22
1 Answers
Depending on what you exactly want to do, you either run the Tcl script as a subprocess or embed a Tcl interpreter instance and use that. I'll assume that it is the latter.
Tcl is, apart from everything else, a (mainly) C library (and its header file is intentionally made compatible with being used from both C++ and Objective C). Thus:
#include <tcl.h>
#include <stdexcept>
#include <string>
public class TclInterpreter {
private:
Tcl_Interp *interp;
public:
TclInterpreter(const char *argv0 = nullptr) : interp(nullptr) {
static bool initLib;
if (!initLib) {
Tcl_FindExecutable(argv0);
initLib = true;
}
interp = Tcl_CreateInterp();
if (!interp) throw new std::runtime_error("failed to initialise Tcl library");
}
~TclInterpreter() {
if (interp) Tcl_DeleteInterp(interp);
}
std::string evalFile(const std::string &filename) {
// This next line is the CRITICAL one!
int code = Tcl_EvalFile(interp, filename.c_str());
if (code >= TCL_ERROR) {
// You should make your own exception, but I've lost patience typing it out
// This throws the exception message; it lasts until you use the interpreter again
throw Tcl_GetStringResult(interp);
}
return std::string(Tcl_GetStringResult(interp));
}
}
You'd then be able to call that a bit like this:
TclInterpreter interpreter(argv[0]); // << omit ‘argv[0]’ if you don't know it
std::string filename("my_file.tcl");
std::string result = interpreter.evalFile(filename);
std::cout << result << '\n';
You'd need to make sure that tcl.h
is found when compiling, and you'd need to make sure that you link against libtcl.so
/libtcl.dll
/libtcl.dylib
when linking. (The exact filename to link against may depend on exactly which version of Tcl you're wanting to link and what OS you're on.)
For a more sophisticated version of this that probably does a lot better job of error handling — the part I've sort-of glossed over rather above! — among other things (but is consequently more work to understand), see C++/Tcl. However, that doesn't seem to expose an evalFile
method at this point so you'd need to run source my_file.tcl
as a little scriptlet. (Tcl_EvalFile()
is basically the implementation of the Tcl source
command.)

- 1
- 1

- 133,037
- 18
- 149
- 215
-
Standard Tcl's API will remain strict C. Not a chance of us changing that. We might use other languages in the implementation where that simplifies things for us. – Donal Fellows May 24 '20 at 18:36