- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
12 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Thanks for the advice.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Check out CVF's Portability Library - it offers some C-like functions such as FSEEK that operate on Fortran I/O units.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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),
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),
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How are you linking? These should be pulled in for you automatically from DFWIN.LIB.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
(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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"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!
Nothing disabed. Thanks for your expert advice. Enjoy the rest of your Labor Day. I will enjoy mine!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page