【发布时间】:2014-04-12 16:48:44
【问题描述】:
我正在尝试在我的 C++ 程序中找到对 "system"(来自 stdlib.h)的调用的替代方法。 到目前为止,我一直在使用它在我的程序中调用 g++ 进行编译,然后在用户选择的目录中链接可变数量的源文件。
这里我有一个示例,该命令大致如下所示:"C:/mingw32/bin/g++.exe -L"C:\mingw32\lib" [...]"
但是,我遇到的问题是(至少对于我正在使用的 MinGW 编译器)我在执行命令时收到错误 “命令行太长”字符串太长。 就我而言,它大约有 12000 个字符长。所以我可能需要另一种方式来调用 g++。 此外,我了解到您通常无论如何都不应该使用“系统”:http://www.cplusplus.com/forum/articles/11153/
所以我需要一些替代品(它也应该尽可能独立于平台,因为我希望程序可以在 Windows 和 Linux 上运行)。 我找到了一位通常看起来非常适合的候选人:
-
_execv / execv:
独立于平台,但是:
a) http://linux.die.net/man/3/exec 说“exec() 系列函数用新的进程映像替换当前进程映像”。那么我是否需要先调用 "fork" 以使 C++ 程序不被终止? Windows/MSVC 上也可以使用 fork 吗?
b) 使用“system”,我测试了返回值是否为0,看看是否可以编译源文件。这将如何与 exec 一起工作?如果我正确理解手册页,它只会返回创建新进程的成功而不是 g++ 的状态吗?我可以使用哪个函数暂停我的程序以等待 g++ 完成并获取返回值?
总而言之,我不太确定我应该如何处理这个问题。你有什么建议? Java (Runtime.getRuntime().exec(command)) 或 Eclipse C++ IDE 等多平台程序如何在内部解决这个问题?您建议我如何以独立于系统的方式调用 g++ - 使用尽可能多的参数?
编辑: 现在我正在使用以下代码 - 我只在 Windows 上测试过它,但至少在那里它似乎按预期工作。谢谢你的想法,jxh! 也许我将来会考虑通过使用相对路径来缩短命令。然后我必须找到一种独立于平台的方法来更改新进程的工作目录。
#ifdef WIN32
int success = spawnv(P_WAIT, sCompiler.c_str(), argv);
#else
pid_t pid;
switch (pid = fork()) {
case -1:
cerr << "Error using fork()" << endl;
return -1;
break;
case 0:
execv(sCompiler.c_str(), argv);
break;
default:
int status;
if (wait(&status) != pid) {
cerr << "Error using wait()" << endl;
return -1;
}
int success = WEXITSTATUS(status);
}
#endif
【问题讨论】:
-
fork()适用于支持该调用的 POSIX 系统,而 MINGW 不为 Windows 实现它。应该有一个<process.h>头文件提供spawn*(),这是MINGW 替代fork()/exec()调用。 -
我不敢问为什么您需要超过 12,000 个字符的命令行。我读过篇幅较少的短篇小说。
-
该命令的问题在于它包含每个文件的源目录路径(例如“C:/Users/Christoph/C++-Projekte/GameProgramming/LandsOfShadow/leveleditor_interface/Audio/Audio .o”)。有数百个源文件,这会变得很长......
-
你能解析出重复的部分,或者至少设置更短的符号链接到目录吗?
-
因为所有源文件都有相同的父文件夹,我可以通过将 g++ 的工作目录更改为源目录来缩短它们,然后只使用“main.o”等相对文件路径而不是绝对路径,例如“C:/Users/Christoph/C++-Projekte/GameProgramming/LandsOfShadow/leveleditor_interface/main.cpp”。但是,我不确定如何设置 g++ 进程的工作目录。
标签: c++ c process cross-platform exec