title: Python subprocess Popen: Send binary data to C++ on Windows
body: <p>After three days of intensive googleing and stackoverflowing I more or less got my program to work. I tried a lot of stuff and found a lot of answers somehow connected to my problem, but no working solution. Sry should I have missed the right page!! I'm looking forward to comments and recommendations.</p>
  
  <p>Task:</p>
  
  <ul>
  <li>Send binary data (floats) from python to C++ program, get few floats back</li>
  <li>Data is going to be 20ms soundcard input, latency is a bit critical</li>
  <li>Platform: Windows (only due to drivers for the soundcard...)</li>
  <li>Popen with pipes, but without communicate, because I want to keep the C++ program opened</li>
  </ul>
  
  <p>The whole thing worked just fine on ubuntu with test data. On Windows I ran into the binary stream problem: Windows checks the float stream for EOF character and finds it randomly. Then everything freezes, waiting for instream data which is just behind the "eof" wall. Or so I picture it.</p>
  
  <p>In the end these two things were necessary:</p>
  
  <pre><code>#include &lt;io.h&gt;
  #include &lt;fcntl.h&gt;
  </code></pre>
  
  <p>and</p>
  
  <pre><code>if (_setmode(_fileno(stdin), _O_BINARY) == -1) 
    {cout &lt;&lt; "binary mode problem" &lt;&lt; endl; return 1;};
  </code></pre>
  
  <p>in C++ as described here: <a href="https://msdn.microsoft.com/en-us/library/aa298581%28v=vs.60%29.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/aa298581%28v=vs.60%29.aspx</a>. </p>
  
  <ul>
  <li>cin.ignore() freezes using binary mode! Guess since there's no eof anymore. Did not try/think about this too thoroughly though</li>
  <li>cin.read(mem,sizeof(float)*length) does the job, since I know the length of the data stream</li>
  <li>Compiled with MinGW</li>
  </ul>
  
  <p>and in the Python code same thing! (forgot this first, cost me a day):</p>
  
  <pre><code>if sys.platform.find("win") &gt; -1:
    import msvcrt,os      
    process = subprocess.Popen("cprogram.exe",stdin=subprocess.PIPE,stdout=subprocess.PIPE,bufsize=2**12)
    msvcrt.setmode(process.stdin.fileno(), os.O_BINARY)
  </code></pre>
  
  <p>and</p>
  
  <pre><code>process.stdin.write(data.tostring())
  </code></pre>