我有一个字符串命令,我想在写入其输入和读取其输出时异步执行。听起来很简单,对,魔鬼就在跨平台。我的目标是 MSVC/Win32 和 gcc/Linux,显然希望编写最少数量的特定于平台的代码。我的 google-fu 让我失望了,我的查询噪音太大,所以我从我所知道的开始。
popen - 又好又简单,返回 FILE* 在任何地方都很容易使用。但这是MSDN 对 _popen 的看法:
如果在 Windows 程序中使用,_popen 函数会返回导致程序无限期停止响应的无效文件指针。_popen 在控制台应用程序中正常工作。要创建重定向输入和输出的 Windows 应用程序,请参阅在平台 SDK 中创建具有重定向输入和输出的子进程。
所以 popen 是不可能的(编辑:因为我希望我的代码在 GUI 应用程序中工作)。在我看来,Windows 的做法相当丑陋和冗长。我可以使用特定于平台的生成代码,但我希望至少 I/O 代码是相同的。HANDLE
但是,在这里,我在 WinAPI和 CFILE*
以及int
文件描述符之间碰壁了。有没有办法将a“转换”HANDLE
为FILE*
或int
fd,反之亦然?(谷歌再次让我失望了,我尝试的所有关键字都被过度使用了)
有没有更好的方法用很少的特定于平台的代码来完成整个事情?
外部库并非不可能,但是依赖项维护很痛苦,尤其是在多个平台上,所以我想减少依赖项。我也没有在 boost 中找到这样的库。
只是为了记录,最后对我有用的东西。在 Windows/MSVC 上,CreatePipe()
+如此处CreateProcess()
所述,使用后跟进入进程输入和输出。在 Linux/GCC 上,这里没有什么新鲜事,创建s; 然后是管道;; 在相关的文件描述符上。这样,只有进程生成代码是平台相关的(这没关系,因为在 Windows 上我想控制其他参数),写入输入和读取输出是通过标准和相关函数完成的。_open_osfhandle()
_fdopen()
FILE*
pipe()
fork()
dup2()
exec()
fdopen()
STARTUPINFO
FILE*