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.
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.)