【发布时间】:2010-05-27 18:34:06
【问题描述】:
boost (c++) 库中是否有任何 WinAPI WinExec 模拟?我需要从我的程序运行可执行文件,并将参数传递给它。我应该为此使用任何其他跨平台库,还是自己处理我的程序编译的操作系统?
【问题讨论】:
-
感谢您的回答,我停止了 spawnl() 函数,因为我需要非阻塞执行。
标签: c++ boost cross-platform
boost (c++) 库中是否有任何 WinAPI WinExec 模拟?我需要从我的程序运行可执行文件,并将参数传递给它。我应该为此使用任何其他跨平台库,还是自己处理我的程序编译的操作系统?
【问题讨论】:
标签: c++ boost cross-platform
重要提示:请参阅最后的 POSIX 系统更新。
我的意见是你应该使用你希望支持的各种平台提供的 API/系统调用,或者使用某种抽象层(Noah Roberts 提到的 Boost.Process 库可能是一个想法)来避免处理特定于平台的细节。
我强烈反对使用system 函数,因为它不打算启动您指定的进程,而是应该将您指定的字符串传递给“系统默认shell”或“命令处理器”(如果任何)。这有几个缺点:
system 的文档可以用“未定义的行为”替换而不会造成太大损失——实际上是it is quite like that。我为什么这么说?因为:
system 在当前平台上具有某种意义,因为根本没有“默认外壳”。但这是一个极端情况,通常不是问题——而且也很容易被抓住(if(system(NULL)==0) 没有外壳);真正的问题是/bin/shcommand.com 和 cmd.exe ,在另一个操作系统上它仍然是另一回事。因此,您不确定,例如,如何转义路径中的空格,或者是否应该引用路径;哎呀,你甚至不知道这样的 shell 是否需要一些特殊的命令来启动可执行文件!system返回时,shell将被终止,但你不知道shell是否会等待生成的过程结束;具体示例:cmd.exe 不会在返回之前等待 GUI 可执行文件结束,而在 Linux 上,GUI 可执行文件与所有其他可执行文件一样是可执行文件,并且没有这种特殊处理。在这种情况下,您必须为 Windows 创建一个特殊情况,并创建一个类似 @987654323@ /wait youexecutable.exe 的命令字符串 - 希望解释器的版本仍然(或仍然,取决于 Windows 的版本)支持该语法。而 IIRC start 在 Windows 9x 和 Windows NT 系列上有不同的选项,所以你甚至不确定。system 返回值与命令解释器返回码相关。就system 而言,如果shell 启动,则调用成功,system 认为的错误就结束了。 因为在一个好的应用程序中,您至少需要知道调用是阻塞还是非阻塞,获取有意义的退出代码(由您启动的应用程序实际返回的退出代码),确定应用程序是否已经开始,有有意义的错误代码以防出现问题,system 很可能不适合您的需求;要获得任何这些保证,您必须使用特定于平台的 hack 或无保证的假设,从而浪费了 system 的所有跨平台“兼容性”。
所以,我再说一遍:使用各种平台提供的系统调用(例如,POSIX 上的fork+exec,Windows 上的CreateProcess),它们准确地指定了它们保证做什么,或者使用第三方抽象代码; system的方式肯定不好。
更新:因为当我写这个答案时,我了解到在 POSIX 系统上 system is specified way better - 特别是,它被强制执行命令使用/bin/sh -c command,阻塞直到shell进程终止。
sh 行为,反过来,is mandated in several ways by POSIX;因此,在 POSIX 系统上,“结果的不可预测性”下列出的一些缺点不再适用:
sh 东西(例如,没有 bashisms),你就安全了;waitpid成功,...,你应该get a copy of the error code of the executed program
因此,如果您在 POSIX 上运行,情况就不会那么悲惨了;相反,如果您必须便携,请继续避免使用system。
【讨论】:
system() 有什么问题,它是标准 C++ 的一部分?见http://www.cplusplus.com/reference/clibrary/cstdlib/system。
【讨论】:
我认为有一个库正在尝试进入 boost,名为 Boost.Process。你必须找到它的下载,可能在沙盒或其他东西中。
【讨论】:
你可能想看看这个关于 win32 上的 popen() 的问题:popen
【讨论】: