I need to launch some script using QProcess.

For this, under windows, I use QProcess::execute("cmd [...]");.

However, this won't work if I go under some other OS such as Linux.

So, I was wondering if the best solution to make that code portable, would be to interfere with a mutliplatform scripting solution, such as TCL for exemple.

So I use : QProcess:execute("tclsh text.tcl"); and it works.

But, I got three questions concerning that problem. Because I'm not sure of what I've done.

  • Will execute() execute tclsh with the file test.tcl both under Windows and Linux wherever I execute it ? It seems to do so, but I want to be sure ! Is there any bad scenario that can happen ?
  • Is this a good solution ? I know lots of people have way more experience than I do, and I'd be grateful for anything I could learn !
  • Why not using std::system() ? Is it less portable ?
有帮助吗?

解决方案

While this isn't a total answer, I can point out a few things.

In particular, tclsh is quite happy under Windows; it's a major supported platform. The main problem that could happen in practice is if you pass a filename with a space in it (this is distinctly more likely under Windows than on a Unix due to differences in community practice). However, the execute() as you have written it has no problems. Well, as long as tclsh is located on the PATH.

The other main option for integrating Tcl script execution with Qt is to link your program against the Tcl binary library and use that. Tcl's API is aimed at C, so it should be pretty simple to use from C++ (if a little clunky from a C++ perspective):

// This holds the description of the API
#include "tcl.h"

// Initialize the Tcl library; *call only once*
Tcl_FindExecutable(NULL);

// Make an evaluation context
Tcl_Interp *interp = Tcl_CreateInterp();

// Execute a script loaded from a file (or whatever)
int resultCode = Tcl_Eval(interp, "source test.tcl");

// Check if an error happened and print the error if it did
if (resultCode == TCL_ERROR) {
    std::cerr << "ERROR: " << Tcl_GetString(Tcl_GetObjResult(interp)) << std::endl;
}

// Squelch the evaluation context
Tcl_DeleteInterp(interp);

I'm not a particularly great C++ coder, but this should give the idea. I have no idea about QProcess::execute() vs std::system().

其他提示

A weak point of your solution is that on windows you'll have to install tclsh. There is no tclsh on Solaris either. May be somewhere else.

Compared to std::system(), QProcess gives you more control and information about the process of executing your command. If all you need is just to execute script (without receiving the output, for example) - std::system() is a good choice.

What I've used in a similar situation:

#ifdef Q_OS_WIN
    mCommand = QString("cmd /C %1 %2").arg(command).arg(args);
#else
    mCommand = QString("bash %1 %2").arg(command).arg(args);
#endif
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top