How can you capture a DLL's stdout and/or stderr in Python on Windows? For example, this prints "hello" to stderr, but it should be possible to capture the "hello" as a string instead of printing it:
import ctypes
string = b'hello\n'
ctypes.cdll.msvcrt._write(2, string, len(string))
Here's what doesn't work:
- Temporarily assigning
sys.stderrto aStringIO(or equivalently, usingcontextlib.redirect_stdout) doesn't capture the output because it's from a C library function, not a Python print statement. This doesn't work on Linux either. - Using
os.dup2()and reading from a pipe on a separate thread, as suggested here, merely suppresses the output without capturing it. - Using
ctypes.cdll.kernel32.GetStdHandle()andctypes.cdll.kernel32.SetStdHandle(), as suggested here, gives the errorOSError: [WinError 6] The handle is invalidwhen attempting to print to the modified stderr. - This solution fails because
ctypes.util.find_msvcrt()returnsNonein Python 3.5+, which to my understanding is because Microsoft has transitioned from the Microsoft Visual C++ Runtime (MSVCRT) to the Universal C Runtime (UCRT). Even if I change the linemsvcrt = CDLL(ctypes.util.find_msvcrt())tomsvcrt = ctypes.cdll.msvcrt, it merely suppresses the output without capturing it.
My general impression is that solutions that work on Linux don't work on Windows, and solutions that used to work on Windows no longer do because of the transition to the UCRT.
It's not exactly what you're after, but you may be able to wrap your dll calling in
subprocess