使用 pipe() 和 fdopen() 将数据从 Python 脚本传递到 Windows 中的 C++ 应用程序
Use pipe() and fdopen() to pass data from Python script to C++ application in Windows
我们有一些 Linux/macOS 应用程序,它可以通过传递文件描述符并从中读取数据来与外界通信。通常这样做是为了传递 stdin/stdout 描述符,但是我们使用 pipe() 并且效果很好。除了 MinGW/Windows。
在 Windows 下完成相同工作的推荐方法是什么?传递整个文件句柄,或者有什么好的方法来模拟 small-int-like 描述符?
在Windows中,C文件描述符在进程STARTUPINFO
record in the reserved fields cbReserved2
and lpReserved2
. The protocol is undocumented, but the source is distributed with Visual C++. C functions that use this feature include the _[w]spawn
family of functions and [_w]system
中被继承。 (然而,[_w]system
函数在这方面通常没有用,因为只有直接 cmd.exe 进程继承父进程的文件描述符。CMD 不会将它们传递给子进程。)
在Python 2.7中,os.pipe
是通过调用CreatePipe
, which returns non-inheritable file handles for the read and write ends of the pipe. These handles are then manually wrapped with inheritable file descriptors via _open_osfhandle
实现的,但是底层的OS句柄仍然是不可继承的。要解决此问题,请通过 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文件句柄,那至少是一致的。
我们有一些 Linux/macOS 应用程序,它可以通过传递文件描述符并从中读取数据来与外界通信。通常这样做是为了传递 stdin/stdout 描述符,但是我们使用 pipe() 并且效果很好。除了 MinGW/Windows。 在 Windows 下完成相同工作的推荐方法是什么?传递整个文件句柄,或者有什么好的方法来模拟 small-int-like 描述符?
在Windows中,C文件描述符在进程STARTUPINFO
record in the reserved fields cbReserved2
and lpReserved2
. The protocol is undocumented, but the source is distributed with Visual C++. C functions that use this feature include the _[w]spawn
family of functions and [_w]system
中被继承。 (然而,[_w]system
函数在这方面通常没有用,因为只有直接 cmd.exe 进程继承父进程的文件描述符。CMD 不会将它们传递给子进程。)
在Python 2.7中,os.pipe
是通过调用CreatePipe
, which returns non-inheritable file handles for the read and write ends of the pipe. These handles are then manually wrapped with inheritable file descriptors via _open_osfhandle
实现的,但是底层的OS句柄仍然是不可继承的。要解决此问题,请通过 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文件句柄,那至少是一致的。