C++ QProcess多平台命令
我需要使用QProcess启动一些脚本 为此,在windows下,我使用C++ QProcess多平台命令,c++,linux,qt,tcl,multiplatform,C++,Linux,Qt,Tcl,Multiplatform,我需要使用QProcess启动一些脚本 为此,在windows下,我使用QProcess::execute(“cmd[…]”) 但是,如果我使用其他操作系统(如Linux),这将不起作用 因此,我想知道使代码可移植的最佳解决方案是否是干扰多平台脚本解决方案,例如TCL 所以我使用:QProcess:execute(“tclsh text.tcl”)并且它可以工作 但是,关于这个问题,我有三个问题。因为我不确定我做了什么 将execute()在Windows和Linux下执行tclsh文件tes
QProcess::execute(“cmd[…]”)代码>
但是,如果我使用其他操作系统(如Linux),这将不起作用
因此,我想知道使代码可移植的最佳解决方案是否是干扰多平台脚本解决方案,例如TCL
所以我使用:QProcess:execute(“tclsh text.tcl”)代码>并且它可以工作
但是,关于这个问题,我有三个问题。因为我不确定我做了什么
- 将
execute()
在Windows和Linux下执行tclsh
文件test.tcl
?看起来是这样,但我想确定一下!有没有可能发生什么糟糕的情况
- 这是一个好的解决方案吗?我知道很多人都比我有更多的经验,我会感激我能学到的一切李>
- 为什么不使用
std::system()
?它的便携性差吗
解决方案的一个弱点是,在windows上,您必须安装
tclsh
。Solaris上也没有tclsh
。可能在别的地方
与std::system()
相比,QProcess
提供了有关执行命令过程的更多控制和信息。如果您只需要执行脚本(例如,不接收输出)-std::system()
是一个不错的选择
我在类似情况下使用的:
#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
虽然这不是一个完整的答案,但我可以指出一些事情
特别是,tclsh
在Windows下非常开心;这是一个主要的支持平台。在实践中可能出现的主要问题是,如果传递的文件名中有空格(由于社区实践的不同,在Windows下比在Unix上更可能出现这种情况)。但是,您编写的execute()
没有问题。那么,只要tclsh
位于路径上
将Tcl脚本执行与Qt集成的另一个主要选项是将程序链接到Tcl二进制库并使用它。TCL的API是针对C的,所以从C++中使用它(如果有一个C++的小笨拙)应该是非常简单的:
//这包含API的描述
#包括“tcl.h”
//初始化Tcl库*只打一次电话*
Tcl_FindExecutable(NULL);
//创建一个评估上下文
Tcl_Interp*Interp=Tcl_CreateInterp();
//执行从文件(或其他文件)加载的脚本
int resultCode=Tcl_Eval(interp,“source test.Tcl”);
//检查是否发生错误,如果发生,则打印错误
if(resultCode==TCL\u错误){
另外,嵌入还提供了一些其他优势:一种成熟的脚本语言,具有良好的文档,更多的控制(您可以设置变量,读回变量,将自己的命令添加到Tcl interp…)虽然使用外部进程总是有自己进程的开销。哦,是的,我需要安装TCLSH。但是如果我使用多个操作系统,我不知道我会在代码中使用多个#ifdef
脚本,还是在每个编译环境中安装TCLSH。这似乎是一个选择问题。
// 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);