Software Archive
Read-only legacy content

File Handles

Intel_C_Intel
Employee
1,460 Views
I have some very specialized C file-reading functions that I would like to use in my CVF Windows program. Several of these functions require that I pass the handle of the open file. How do I get the file handle in CVF?
0 Kudos
12 Replies
Steven_L_Intel1
Employee
1,460 Views
I don't see a way to do this. What sort of specialized functions are these? Perhaps they can be simuilated by other Fortran calls...

Steve
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,460 Views
A general rule of thumb when working with I/O is that you mustn't mix libraries when working with files; that is, you can use Fortran's OPEN...WRITE/READ...CLOSE, or C's fopen...fprintf/fscanf...fclose, or Win32 CreateFile...WriteFile/ReadFile...CloseHandle -- but you shouldn't mix the methods, at least not simultaneously on the same file.

So, if I got you right that the C file expects a Win32-based handle, you can open it in Fortran with CreateFile (see SDK documentation), which returns its handle. If it expects another library-based handle (such as standard C RTL fopen), you'll have to create C wrapper functions and link them with the rest or fortran sources.
0 Kudos
Intel_C_Intel
Employee
1,460 Views
The advice on not mixing libraries opened my eyes! I certainly was going to try something along that line when using my C functions. And so I have bit the bullet, translated the C to Fortran. At present I am using open/read, but would prefer to use the CreateFile family because SetFilePointer would be most useful for this project. If time allows....

Thanks for the advice.
0 Kudos
Steven_L_Intel1
Employee
1,460 Views
Check out CVF's Portability Library - it offers some C-like functions such as FSEEK that operate on Fortran I/O units.

Steve
0 Kudos
pcurtis
Beginner
1,460 Views
Here are some routines which implement handle-based file i/o in F90,
using the Win32 API functions. Not true Fortran, not portable, but
IMHO a whole lot more versatile than the the limited i/o capabilities
of Fortran, since one can transfer a specified byte count to/from a
specified offset position in a file, without any need for records or
any other form of internal formatting. (If the posted/rec'd versions
of the code are illegible, email me at pcurtis@kiltel.com & I'll be
glad to send the code directly).

!=======================================================================
! Files/disk access routines
!=======================================================================
MODULE filesubs
USE kernel32 ! Win32 API interfaces

CONTAINS

FUNCTION file_exists (fname) RESULT (size)
IMPLICIT NONE
TYPE(T_WIN32_FIND_DATA) :: fdata
CHARACTER(LEN=*),INTENT(IN) :: fname ! full pathname to file
INTEGER :: size
IF (FindFirstFile(fname,fdata) /= INVALID_HANDLE_VALUE) THEN
size = fdata%nFileSizeLow
ELSE
size = -1
ENDIF
END FUNCTION file_exists

FUNCTION open_the_file (fullpath, rwmode) RESULT (ihandl)
IMPLICIT NONE
INTEGER :: access,ihandl
CHARACTER(LEN=*),INTENT(IN) :: fullpath,rwmode

! old-style Fortran file open
IF (rwmode == 'F') THEN
IF (file_exists(fullpath) > 0) THEN
OPEN (ihandl,FILE=fullpath,STATUS='OLD')
ELSE
OPEN (ihandl,FILE=fullpath,STATUS='NEW')
END IF
RETURN

! Win32 file opens
ELSE IF (rwmode == 'R') THEN
access = GENERIC_READ
ELSE
access = IOR(GENERIC_READ,GENERIC_WRITE)
END IF

ihandl = CreateFile (fullpath, &
access, &
FILE_SHARE_READ, &
NULL_SECURITY_ATTRIBUTES, &
OPEN_ALWAYS, &
FILE_ATTRIBUTE_NORMAL, &
NULL )
END FUNCTION open_the_file

SUBROUTINE full_path (root,subdir,fnam,extn,pathname)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN) :: root,subdir,fnam,extn
CHARACTER(LEN=*),INTENT(OUT) :: pathname
CHARACTER(LEN=1),PARAMETER :: slash = '', dot = '.'
WRITE (pathname,'(8A)') root(1:LEN_TRIM(root)), &
slash, &
subdir(1:LEN_TRIM(subdir)), &
slash, &
fnam(1:LEN_TRIM(fnam)), &
dot, &
extn(1:MIN0(3,LEN_TRIM(extn))), &
CHAR(0)
END SUBROUTINE full_path

SUBROUTINE rw_file (rwmode,ihandl,nbytes,offset,loc_pointer)
IMPLICIT NONE
CHARACTER(LEN=1),INTENT(IN) :: rwmode
INTEGER,INTENT(IN) :: ihandl,nbytes,offset
INTEGER,INTENT(IN) :: loc_pointer
INTEGER :: nact
LOGICAL :: rslt

! position pointer if offset is provided
IF (offset > 0) rslt = SetFilePointer (ihandl,offset,NULL,FILE_BEGIN)

IF (rwmode == 'R') THEN
rslt = ReadFile (ihandl, & ! file handle
loc_pointer, & ! address of data
nbytes, & ! byte count to read
LOC(nact),
0 Kudos
Intel_C_Intel
Employee
1,460 Views
These look like excellent routines. I had already tried to implement the WinAPI functions on my own, because I need byte transfer, and need to be able to position the file for input/output. However, I quit after a few hours because I couldn't solve one of the compilation problems. I am going to try these out right away.
0 Kudos
Intel_C_Intel
Employee
1,460 Views
Having problems with the defined parameters for CreateFile (in Paul's module). Same problems that I had when I tried to do it myself. I am running CVF 6.1A, compiling a quickwin pgm, and get the following error message for link:

Linking...
Filesubs.obj : error LNK2001: unresolved external symbol _DFWINTY_mp_NULL_SECURITY_ATTRIBUTES
Filesubs.obj : error LNK2001: unresolved external symbol _DFWINTY_mp_NULL_OVERLAPPED

What module do I need to include? Why aren't these defined in dfwinty?
0 Kudos
Steven_L_Intel1
Employee
1,460 Views
How are you linking? These should be pulled in for you automatically from DFWIN.LIB.

Steve
0 Kudos
Intel_C_Intel
Employee
1,460 Views
Linking via Visual Fortran IDE.
(Is it important that I also have a version of Microsoft Visual Studio 6.0 on my hard drive? Is there cross-talk here?) Anyway, I added dfwin.lib to the link libraries and now all is fine. Thanks everyone.
0 Kudos
Steven_L_Intel1
Employee
1,460 Views
You should not have needed to add dfwin.lib unless you disabled processing of default libraries. It does not matter if you have Visual Studio 6 installed.

Steve
0 Kudos
Intel_C_Intel
Employee
1,460 Views
"running CVF 6.1A, compiling a quickwin pgm"

Nothing disabed. Thanks for your expert advice. Enjoy the rest of your Labor Day. I will enjoy mine!
0 Kudos
Intel_C_Intel
Employee
1,460 Views
Correction. My thinking disabled. Already half way through a glass of wine. I had checked "Ignore all default libraries", to avoid a conflict in libcd.
0 Kudos
Reply