我们有一些 Linux/macOS 应用程序,它可以通过传递文件描述符并从中读取数据来与外界通信。通常这样做是为了传递 stdin/stdout 描述符,但是我们使用 pipe() 并且效果很好。除了 MinGW/Windows。 在 Windows 下做同样的工作的推荐方法是什么?传递整个文件句柄,或者有模拟 small-int-like 描述符的好方法?
最佳答案
在Windows中,C文件描述符在进程中被继承STARTUPINFO
在保留字段 cbReserved2
和 lpReserved2
中记录。该协议(protocol)未记录,但源代码随 Visual C++ 一起分发。使用此功能的 C 函数包括 _[w]spawn
函数族和[_w]system
. (然而,[_w]system
函数在这方面通常没有用,因为只有直接的 cmd.exe 进程继承父进程的文件描述符。CMD 不会将它们传递给子进程。)
在 Python 2.7 中,os.pipe
是通过调用 CreatePipe
实现的, 它为管道的读写端返回不可继承的文件句柄。然后通过 _open_osfhandle
使用可继承的文件描述符手动包装这些句柄。 ,但底层操作系统句柄仍然不可继承。要解决此问题,请通过 os.dup
复制文件描述符,它会在内部复制可继承的文件句柄,然后关闭源文件描述符。例如:
pread, pwrite = os.pipe()
pwrite_child = os.dup(pwrite)
os.close(pwrite)
Python 的subprocess
模块通常是创建子进程的首选方式。但是,在这种情况下我们不能使用 subprocess
,因为它不支持通过 STARTUPINFO
(*) 继承文件描述符。这是一个使用 os.spawnv
的示例相反:
rc = os.spawnv(os.P_WAIT, 'path/to/spam.exe', ['spam', 'arg1', 'arg2'])
(*) Windows Python 内部使用 C 运行时文件 API(例如 _wopen
、_read
、_write
)是一个尴尬的情况,但有些地方不支持 C 文件描述符。它应该硬着头皮直接使用 Windows 文件 API 和 OS 文件句柄,那么它至少会保持一致。
关于python - 使用 pipe() 和 fdopen() 将数据从 Python 脚本传递到 Windows 中的 C++ 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58736093/