c fortran gzip gfortran fortran-iso-c-binding

¿Por qué print statement cambia el comportamiento de gzread?



fortran gzip (1)

Intento leer un archivo gzip en Fortran usando las funciones C gzopen, gzread y gzclose de la biblioteca zlib . Mi subrutina funciona correctamente cuando contiene una instrucción de impresión, pero da un Z_STREAM_ERROR (-2) sin ella. ¿Qué está causando esto y cómo puedo solucionarlo?

module gzmodule use :: iso_c_binding implicit none private public fastunzip interface type(c_ptr) function gzopen(filename,mode) bind(c) use :: iso_c_binding character(kind=c_char), dimension(*) :: filename character(kind=c_char), dimension(*) :: mode end function gzopen end interface interface integer(c_int) function gzread(gzfile,buffer,length) bind(c) use :: iso_c_binding type(c_ptr), value :: gzfile character(len=1,kind=c_char) :: buffer(*) integer(c_int) :: length end function gzread end interface interface integer(c_int) function gzclose(gzfile) bind(c) use :: iso_c_binding type(c_ptr), value :: gzfile end function end interface contains subroutine fastunzip(filename, isize,abuf,ierr) use :: iso_c_binding character(len=*,kind=c_char), intent(in) :: filename integer(c_int), intent(out) :: isize character(len=1,kind=c_char), intent(inout) :: abuf(:,:,:,:) integer(4), intent(out) :: ierr type(c_ptr) :: gzfile integer(c_int) :: iclose logical :: c_associated ierr = 1 !! indicates that an error has occured isize = 0 gzfile = gzopen(trim(filename)//c_null_char,"rb") if (.not.c_associated(gzfile)) return isize = gzread(gzfile,abuf,size(abuf)) print*,isize !! why do I need this for it to work? if (isize.ne.size(abuf)) return iclose = gzclose(gzfile) if (iclose.ne.0) return ierr = 0 !! success end subroutine fastunzip end module gzmodule program main use gzmodule implicit none character(100) :: filename = ''./f10_19950120v7.gz'' integer(4) :: isize integer(4) :: ierr logical(4) :: exists integer(4), parameter :: nlon = 1440 integer(4), parameter :: nlat = 720 integer(4), parameter :: nvar = 5 integer(4), parameter :: nasc = 2 character(1) :: abuf(nlon,nlat,nvar,nasc) inquire(file=filename,exist=exists) if (.not.exists) stop ''file not found'' call fastunzip(filename, isize,abuf,ierr) print*,''return value of isize '',isize if (ierr.ne.0) stop ''error in fastunzip'' print*,''done'' end program main

Estoy en CentOS y compilando con:

gfortran -o example_usage.exe example_usage.f90 /lib64/libz.so.1

y el archivo de datos está disponible en este sitio .


En la subrutina fastunzip declaras logical :: c_associated . Sin embargo, obtienes esta función mediante la asociación de uso (de iso_c_binding ), por lo que debes eliminar esa línea.

Mi gfortran instalado (4.8) lo marca como un error, ¿así que supongo que tienes una versión anterior? Pero una vez que elimino esa línea, su código parece funcionar incluso sin la print , por lo que quizás valga la pena intentarlo.

En una nota de estilo, recomendaría use, intrinsic :: iso_c_binding , quizás incluso con only (lo que también c_associated que c_associated es a través de la asociación de uso).