是否有一种跨平台的方法可靠地找到带有ctypes的stdout文件描述符?

Igu*_*aut 5 python macos ctypes posix darwin

我有一些代码使用ctypes来尝试确定指向的文件sys.stdout是否实际 stdout.我知道在任何符合POSIX标准的系统上,甚至在Windows上,如果这样做应该是安全的sys.stdout.fileno() == 1,所以我的问题不是如何做到这一点.

在我的代码中(已经将ctypes用于与我的问题无关的东西)我不小心有类似的东西:

libc = ctypes.CDLL(ctypes.util.find_library('c'))
real_stdout = libc.fileno(ctypes.c_void_p.in_dll(libc, 'stdout'))
if sys.stdout.fileno() == real_stdout:
    ...
Run Code Online (Sandbox Code Playgroud)

这在Linux上完全正常,所以我并没有真正考虑它.它比硬编码1作为文件描述符看起来更好,更易读.但几天后我发现我的代码不能用于OSX.

它结束了OSX的libc不会导出任何名为'stdout'的符号.相反,它的stdio.h将stdout定义为:

#define stdout __stdoutp
Run Code Online (Sandbox Code Playgroud)

如果我将代码更改为c_void_p.in_dll(libc, '__stdoutp')我的代码按预期工作,但当然这只是OSX.事实证明,Windows有一个类似的问题(至少如果使用MSVC).

我可能只是改变我要使用的代码1,但我的问题仍然存在,出于好奇,如果有一种跨平台的方式来获取stdio指针(以及同样stdinstderr)而不假设它使用符合POSIX的描述符?

Per*_*son 5

就 C 而言,如果您想要兼容性,则必须去查看相关标准。既然你提到了 Windows,我猜你实际上并不需要 POSIX 标准,而是需要 C 标准。

C99 第 7,19,1 节将 stdout 定义为宏,因此不是变量。这意味着您无法依赖使用 dlsym (我假设 in_dll 使用)来查找它。实际的表达式也可以是函数调用或固定地址。也许不太可能,但有可能......

正如注释中所说, fileno 函数又是由 POSIX 定义的,而不是由 C 定义的。C 没有文件描述符的概念。我认为你最好假设 POSIX 并只检查它指定的值 1。