繁体   English   中英

在我的C ++程序中代替对“系统”的调用

[英]Substitute for call to “system” in my C++ program

我试图在我的C ++程序中找到对“系统” (来自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)使用“系统”,我测试了返回值是否为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

如果所有文件都位于(或可以移至)一个(或少量)目录中,那么使用某些命令行选项可能会有所帮助。 给定您到audio.o的示例路径,这将使您的命令行减少大约90%。

-Ldir
Add directory dir to the list of directories to be searched for `-l'.

来自: https : //gcc.gnu.org/onlinedocs/gcc-3.0/gcc_3.html#SEC17

-llibrary
Search the library named library when linking.

在命令中写入此选项的位置会有所不同。 链接器按指定的顺序搜索过程库和目标文件。 因此, foo.o -lz bar.o' searches library '在文件foo.o' but before foo.o -lz bar.o' searches library z'。 如果bar.o' refers to functions in z'中的函数,则可能不会加载这些函数。

链接器在标准目录列表中搜索该库,该库实际上是一个名为“ liblibrary.a”的文件。 链接器然后使用该文件,就好像它是通过名称精确指定的一样。

搜索的目录包括几个标准系统目录以及您用`-L'指定的目录。

通常,以这种方式找到的文件是库文件-归档文件,其成员是目标文件。 链接器通过扫描存档文件来查找成员,这些成员定义了到目前为止已被引用但尚未定义的符号。 但是,如果找到的文件是普通的目标文件,则以通常的方式链接。 使用-l' option and specifying a file name is that之间的唯一区别-l' option and specifying a file name is that -l'用lib' and .a'包围库并搜索多个目录。

来自: http : //gcc.gnu.org/onlinedocs/gcc-3.0/gcc_3.html

这是另一个选择,也许更接近您的需求。 尝试在调用system()之前更改目录。 例如,这就是Ruby中发生的事情……我猜想它在C ++中的作用相同。

> system('pwd')
/Users/dhempy/cm/acts_rateable
=> true
> Dir.chdir('..')
=> 0
> system('pwd')
/Users/dhempy/cm
=> true

如果没有其他答案可以解决,那么这里是另一个。 您可以将环境变量设置为目录的路径,然后在链接到的每个文件之前使用该变量。

我不太喜欢这种方法,因为您必须修改环境,而且我不知道这是否会真正影响命令行限制。 插值命令后可能会应用该限制。 但是,无论如何,都有些事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM