我可以使用boost库来执行跨平台应用程序吗?

Hei*_*erg 2 c++ boost cross-platform

在boost(c ++)库中是否有任何WinAPI WinExec模拟?我需要从我的程序运行可执行文件,并将参数传递给它.我应该使用任何其他跨平台库,还是自己处理我的程序编译的操作系统?

Mat*_*lia 15

重要提示:请参阅POSIX系统最后的更新.

我的观点是你应该使用你希望支持的各种平台提供的API /系统调用,或者使用某种抽象层(Noah Roberts提到的Boost.Process库,可能是一个想法)来避免处理平台 - 具体细节.

我非常不同意使用该system函数,因为它不是为了启动您指定的进程,而是应该将您指定的字符串传递给"系统默认shell"或"命令处理器"(如果有的话).这有几个缺点:

  • 资源浪费; 而不是现在(通常)你正在产生两个过程,其中一个(shell)对你的最终目标没用(开始你想要的过程).这通常可以忽略不计,但如果进程不是轻量级对象(Windows),如果它们的资源不足,则可能会引起注意.
  • 无用的混乱; 我处理过的几个安全套件每当一个未知/不受信任的进程启动一个新进程时就会发出警告; 现在,安全套件将显示其中的两个(并且您正在制作第一个非常不清楚),而不仅仅是显示警告;
  • 结果的不可预测性; 平台无关system的文档可以用"未定义的行为"替换而不会有太多损失 - 实际上就是这样.我为什么这么说?因为:
    • 首先,system在当前平台上甚至没有保证具有某种意义,因为根本就没有"默认外壳".但这是一个极端情况,通常不是一个问题 - 而且也很容易被抓住(if(system(NULL)==0)没有外壳); 真正的问题是
    • 一般来说,你不知道什么 shell是"默认shell",以及它如何解析它的输入; 在Linux上它会通常是 /bin/sh 更新:实际上,这是由POSIX强制执行的,见下文,在Windows上它可能command.com也是如此cmd.exe,在另一个操作系统上它仍然是另一回事.所以,你不确定,例如,如何逃避路径中的空间,或者你应该引用路径; 哎呀,你甚至都不知道这样的shell是否需要一些特殊的命令来启动可执行文件!
    • 更有趣的是:你甚至不知道这个调用是否实际阻塞:你知道到时候system将返回shell将被终止,但是你不知道shell是否会等待生成的进程结束; 具体示例:cmd.exe在返回之前不等待GUI可执行文件结束,而在Linux上,GUI可执行文件是可执行文件,就像所有其他文件一样,并没有这样的特殊处理.在这种情况下,您将不得不为Windows创建一个特殊情况,并创建一个命令字符串start /wait youexecutable.exe- 希望解释器的版本仍然(或者,取决于Windows的版本)支持该语法.IIRC start在Windows 9x和Windows NT系列上有不同的选择,所以你甚至不能确定.
    • 这还不够:您甚至不确定应用程序是否已启动:system返回值是相对于命令解释程序返回代码.就所system涉及的情况而言,如果启动了一个shell,则调用成功,并结束system考虑错误的内容.
    • 然后你留下shell的错误代码 - 关于哪一个,我们什么都不知道.也许它是最后执行的命令的错误代码的复制品; 也许它只是一个相对于shell的错误代码(例如,1 =执行最后一个命令,0 =最后一个命令无效),也许是42个.谁知道?

因为在一个好的应用程序中,您至少需要知道调用是阻塞/非阻塞,以获得有意义的退出代码(您启动的应用程序实际返回的代码),以确保应用程序是否已启动如果出现问题,要有有意义的错误代码,system很可能不适合您的需要; 要获得任何这些保证,您必须使用特定于平台的黑客或无保证的假设,浪费所有跨平台的"兼容性" system.

所以,我将再次说明:使用各种平台提供的系统调用(例如,在POSIX 上的fork + exec,在Windows 上的CreateProcess),它们确切地指定了它们保证要做的事情,或者使用第三方抽象代码; 这种system方式肯定不好.


更新:因为当我写这个答案时,我了解到在POSIX系统system 上指定的方式更好 - 特别是,它要求它将执行命令/bin/sh -c command,阻塞直到shell进程终止.

sh反过来,行为是由POSIX以多种方式强制执行的 ; 因此,在POSIX系统上,"结果的不可预测性"中列出的一些缺点不再适用:

  • 指定了默认的shell,因此,只要你只使用shPOSIX保证的东西(例如没有bashisms),你就是安全的;
  • 该呼叫阻塞;
  • 如果你的命令格式正确,shell本身不会遇到问题,waitpid成功,......,你应该得到执行程序的错误代码的副本

所以,如果你在POSIX上运行,情况就不那么悲惨; 相反,如果你必须便携,请继续避免system.