简体   繁体   English

跨平台重定向本机C / C ++中生成的过程的标准输入和输出(使用解决方案进行编辑)

[英]Cross-platform redirect of standard input and output of spawned process in native C/C++ (edit with solution)

I have a string command I'd like to execute asynchronously while writing to its input and reading its output. 我有一个字符串命令,我想在写入其输入和读取其输出时异步执行。 Sounds easy, right, the devil is in the cross-platform. 听起来很容易,对,魔鬼在跨平台中。 I'm targeting both MSVC/Win32 and gcc/Linux and obviously want to write the minimum amount of platform-specific code. 我的目标是同时使用MSVC / Win32和gcc / Linux,显然想编写最少数量的平台特定代码。 My google-fu has failed me, I get too much noise for my queries, so I started with what I know. 我的google-fu让我失败了,我的查询太多了,所以我从我所知道的开始。

popen - nice and easy, returns FILE* that is easy to consume everywhere. popen-简单易用,返回易于在任何地方使用的FILE *。 But here's what MSDN have to say about _popen : 但是,这是MSDN关于_popen不得不说的

If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. 如果在Windows程序中使用_popen函数,它将返回一个无效的文件指针,该指针会导致程序无限期地停止响应。 _popen works properly in a console application. _popen在控制台应用程序中正常工作。 To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Platform SDK. 要创建重定向输入和输出的Windows应用程序,请参阅Platform SDK中的使用重定向的输入和输出创建子进程。

and so popen is out of the question (edit: because I'd like my code to work in GUI application). 因此popen成为不可能(编辑:因为我希望我的代码在GUI应用程序中工作)。 The Windows way to do it is in my opinion rather ugly and verbose. 我认为Windows的实现方法相当丑陋且冗长。 I could live with platform specific spawn code but I'd want at least the I/O code to be the same. 我可以使用特定于平台的衍生代码,但我至少希望I / O代码相同。 Here, however, I hit a wall between the WinAPI HANDLE s and C FILE* , and int file descriptor. 但是,在这里,我碰到了WinAPI HANDLE和C FILE*以及int文件描述符之间的障碍。 Is there a way to "convert" a HANDLE to FILE* or int fd or vice-versa? 有没有办法将“ HANDLE ”转换为FILE*int fd,反之亦然? (Google failed me once more on this one, all the keywords I tried are way overused) (Google再次使我失败了,我尝试过的所有关键字都被过度使用了)

Is there better way to do the whole thing with little platform-specific code? 有没有更好的方法可以用很少的平台特定代码来完成整个工作?

External libraries are not out of the question, however dependency maintenance is a pain, especially so on multiple platforms so I'd like to reduce dependencies. 外部库并不是没有问题,但是依赖关系维护很麻烦,尤其是在多个平台上,因此我想减少依赖关系。 I didn't find such library in boost also. 我也没有在Boost中找到这样的库。


Just for the record, what worked for me in the end. 仅作记录,最终对我有用。 On Windows/MSVC, CreatePipe() + CreateProcess() as outlined here , using _open_osfhandle() followed by _fdopen() to get FILE* to the process input and output. 在Windows / MSVC, CreatePipe() + CreateProcess()作为概括这里 ,使用_open_osfhandle()然后_fdopen()获得FILE*的过程输入和输出。 On Linux/GCC, nothing new here, creating pipe() s; 在Linux / GCC上,这里没有新内容,创建pipe() fork() then dup2() the pipes; fork()然后dup2()管道; exec() ; exec() ; fdopen() on the relevant file descriptors. 有关文件描述符的fdopen() That way, only the process spawning code is platform dependent (which is ok, as on Windows I'd like to control additional STARTUPINFO parameters), writing input and reading output is done through standard FILE* and related functions. 这样,只有进程产生代码是平台相关的(没关系,就像Windows一样,我想控制其他STARTUPINFO参数),写入输入和读取输出是通过标准FILE*和相关功能完成的。

Give libexecstream a whirl. libexecstream一个旋转。 It's cross platform, and allows you to trap the input, output and error streams of a process asynchronously as C++ style streams. 它是跨平台的,允许您以C ++样式流的形式异步捕获进程的输入,输出和错误流。

I've used it on Linux, Darwin and Windows and it seems to work. 我已经在Linux,Darwin和Windows上使用过它,而且似乎可以正常工作。 It's also pretty lightweight so integrates into projects with little pain, and has a pretty open BSD licence. 它也很轻巧,因此可以轻松集成到项目中,并且具有相当开放的BSD许可证。 I don't think there's any way around using a library (other than writing your own variations for each platform). 我认为没有任何办法可以使用库(除了为每个平台编写自己的变体)。

for converting windows HANDLE s to C file descriptors use _open_osfhandle http://msdn.microsoft.com/en-us/library/bdts1c9x%28VS.71%29.aspx 用于将Windows HANDLE转换为C文件描述符,请使用_open_osfhandle http://msdn.microsoft.com/zh-cn/library/bdts1c9x%28VS.71%29.aspx

EDIT: this example once helped me aswell with a similar problem: http://www.halcyon.com/~ast/dload/guicon.htm 编辑:这个例子曾经帮助我也解决了类似的问题: http : //www.halcyon.com/~ast/dload/guicon.htm

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

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