title: Fortran read from unit from Python
body: <p>I'm looking to work with older Fortran subroutines that read from file-based unit numbers. Here is an example of some fixed-format FORTRAN77, <code>reader.f</code>:</p>
  
  <pre><code>      SUBROUTINE READER(IN,FVAL)
          IMPLICIT NONE
          INTEGER IN
          REAL FVAL
          PRINT *,'READER READING FROM',IN
          READ(IN,*) FVAL
          PRINT *,'READER DONE',FVAL
          RETURN
        END
  </code></pre>
  
  <p>Compile this to a shared library, on Linux:</p>
  
  <pre><code>gfortran -fPIC -shared -o libdusty.so reader.f
  </code></pre>
  
  <p>And here is a basic <a href="https://docs.python.org/library/ctypes.html" rel="nofollow noreferrer">ctypes</a> interface to the library object in Python:</p>
  
  
  
  <pre class="lang-py prettyprint-override"><code>import os
  from ctypes import CDLL, POINTER, c_int32, c_float, byref
  
  c_int32_p = POINTER(c_int32)
  c_float_p = POINTER(c_float)
  
  so = CDLL('./libdusty.so')
  reader = so.reader_
  
  reader.argtypes = [c_int32_p, c_float_p]
  reader.restype = None
  </code></pre>
  
  <p>Without an <code>open</code> statement, Fortran reads from the file <code>#.fort</code>, where <code>#</code> is the file unit number. So continuing from above, I get Python to write a temporary file to read from:</p>
  
  <pre class="lang-py prettyprint-override"><code>fval_in = 43.21
  fnum_in = 12
  fname_in = 'fort.' + str(fnum_in)
  print('Writing ' + fname_in)
  with open(fname_in, 'w') as fp:
      fp.write(str(fval_in) + '\n')
  
  fval_out = c_float(0)
  reader(byref(c_int32(fnum_in)), byref(fval_out))
  print('Received fval: ' + str(fval_out.value))
  os.unlink(fname_in)
  </code></pre>
  
  <p>From a console (which receives <code>stdout</code>), here the full output:</p>
  
  <pre class="lang-py prettyprint-override"><code>Writing fort.12
   READER READING FROM          12
   READER DONE   43.2099991    
  Received fval: 43.2099990845
  </code></pre>
  
  <p><strong>Question</strong>: is a disk-based file object necessary, or is it possible to use a non-file-based stream to read from? A good candidate is <a href="https://docs.python.org/library/io.html#io.BytesIO" rel="nofollow noreferrer"><code>io.BytesIO</code></a>, except that it does not provide <code>fileno()</code>. And a related question: is it possible to use a different file name other than <code>fort.12</code> in this example?</p>