Registrations are now open. Join us today!
There is still a lot of work to do on the wiki yet! More information about editing can be found here.
Already have an account?

Microsoft KB Archive/102698

From BetaArchive Wiki
Knowledge Base

PSS ID Number: 102698

Article Last Modified on 5/5/2001

The information in this article applies to:

  • Microsoft FORTRAN Compiler for MS-DOS 5.1

This article was previously published under Q102698


By calling the file I/O functions in the Windows application programming interface (API), a dynamic-link library (DLL) developed in Microsoft FORTRAN for the Microsoft Windows operating system can read from or write to binary or unformatted files. Invoking the Windows API to provide file I/O services for a FORTRAN DLL will also allow reliable access to the files from the program calling the DLL, even if the program was developed in Microsoft Visual Basic versions 2.0 and later.


The following FORTRAN code demonstrates file I/O on a binary or unformatted file using functions of the Windows API.

The code example below defines the data type used by the bfread and bfwrite functions as REAL*4. You can substitute another data type by changing the declaration in the interface statement.

If an application developed in Visual Basic calls a FORTRAN DLL that uses standard FORTRAN I/O statements to open and close a file, the file may not be available to the parent application. However, if the DLL opens or creates, accesses, and closes the file using functions in the Windows API, the file is available to the parent application or any other application as soon as the DLL closes the file.

The code example uses interface statements for the _hread and _hwrite functions instead of the _lread and _lwrite functions. (The latter functions can process only data items smaller than 64K but they may process these smaller items somewhat more efficiently.) The HUGE.LIB import library, created from HUGE.DEF, is required to call the huge versions of the read and write functions defined in version 3.1 of the Windows API. For more information on Windows API programming, please refer to the Windows SDK documentation.

Sample Code - FORTIO.FOR

C Open an existing file
      interface to integer*2 function lopen
     +  [pascal, alias:'_lopen'](filename, mode)
      character*1 filename[reference]
      integer*2   mode[value]
C        MODE =
C            0     Read-only
C            1     Write-only
C            2     Read and write

C Create a file (erase the old file if one exists)
      interface to integer*2 function lcreat
     +  [pascal, alias:'_lcreat'](filename, mode)
      character*1 filename[reference]
      integer*2   mode[value]
C        MODE =
C            0     Read and write
C            1     Read-only
C            2     Hidden
C            3     System

C Close a file (use with files opened by lcreat or lopen)
      interface to integer*2 function lclose
     +  [pascal, alias:'_lclose'](handle)
      integer*2   handle[value]

C hread and hwrite can read or write a buffer larger than 64K
      interface to integer*4 function hwrite
     +  [pascal, alias:'_hwrite'](handle, buf, size)
      character*1 buf[reference]
      integer*2   handle[value]
      integer*4   size[value]

      interface to integer*4 function hread
     +  [pascal, alias:'_hread'](handle, buf, size)
      character*1 buf[reference]
      integer*2   handle[value]
      integer*4   size[value]

C Seek to a point in a file (used to provide direct file access)
      interface to integer*4 function llseek
     +  [pascal, alias:'_llseek'](handle, offset, origin)
      integer*4   offset[value]
      integer*2   handle[value], origin[value]
C        Origin =
C            0     Offset from start of file
C            1     Offset from current position
C            2     Offset from end of file

C  Read and write binary floating-point data
      interface to integer*4 function bfwrite
     +  [pascal, alias:'_hwrite'](handle, buf, size)
      real*4      buf[reference](1)
      integer*2   handle[value]
      integer*4   size[value]

      interface to integer*4 function bfread
     +  [pascal, alias:'_hread'](handle, buf, size)
      real*4      buf[reference](1)
      integer*2   handle[value]
      integer*4   size[value]

C Write ASCII and binary data
      subroutine testwrite()
      character*30 str
      integer*2 handle, lclose, lcreat
      integer*4 i, hwrite, bfwrite
      real*4 x(20000)  ! Note: X is 80000 bytes

      handle = lcreat('testbf.out'C, 0) ! Create new file
      do i= 2, 20000
        x(i) = x(i - 1) + 3.1415926
      end do
      i = bfwrite(handle, x, 80000)    ! Binary write all of X
      i = lclose(handle)

      handle = lcreat('test.out'C, 0)   ! Create new file
      ! Use an internal write to format output text
      write(str, '(''Test One'', F12.5)') 51.763
      i = hwrite(handle, str, 20)       ! then write output text
      i = lclose(handle)

C Read binary data
      subroutine readbinary()
      character*24 str
      integer*2 j, handle, lclose, lopen, lcreat
      integer*4 i, hwrite, bfread
      real*4 x(20000)  ! Note: X is 80000 bytes
      handle = lopen('testbf.out'C, 2) ! Open existing file
      i = bfread(handle, x, 80000)     ! Binary read all of X
      i = lclose(handle)

      handle = lcreat('testbf_o.out'C, 0) ! Create new file
      do j = 1, 4
         write(str, '(F16.5)') x(j)      ! Convert to text
         i = hwrite(handle, str, 16)     ! Write formatted output
      end do
      write(str, '(F16.5)') x(20000)
      i = hwrite(handle, str, 16)
      i = lclose(handle)

C Randomly access a file
      subroutine testseek()
      character*40 str
      integer*2 handle, lclose, lopen
      integer*4 i, hwrite, llseek, hread

      handle = lopen('test.out'C, 2)
      i = llseek(handle, 4, 0)        ! Position to 4 bytes from start
      i = hread(handle, str, 16)      ! Read 16 characters
      i = llseek(handle, 7, 0)        ! Position to 7 bytes from start
      i = hwrite(handle, str, 16)     ! Overwrite from position 7 on
      i = lclose(handle)


HEAPSIZE       1024


       call testwrite
       print *,"testwrite - Created 'test.out' and 'testbf.out'"
       print *, 'Check them out (Hit return to continue)'
       read *
       call readbinary
       print *, "readbinary - Created 'testbf_o.out'"
       print *, 'Check it out (Hit return to continue)'
       read *
       call testseek   ! modify 'test.out'
       print *, "testseek - Modified 'test.out'"


EXPORTS _hread


all: test.exe

test.exe: fortio.lib test.obj
   link /NOD test.obj, , nul, llibfew + fortio.lib,\ 

test.obj: test.for
   fl /c /MW test.for

fortio.lib: fortio.dll
   implib fortio.lib fortio.dll

fortio.dll: fortio.obj fortio.def huge.lib
   link /NOD fortio.obj, fortio.dll, nul,\ 
       ldllfew.lib + huge.lib, fortio.def;

fortio.obj: fortio.for
   fl /c /Aw /Gw fortio.for

huge.lib: huge.def
   implib huge.lib huge.def

Additional query words: kbinf 5.10

Keywords: KB102698
Technology: kbAudDeveloper kbFORTRAN510DOS kbFortranSearch kbZNotKeyword3