问题描述
我正在编写一个 HDF5 包装子例程,它将从/向 HDF5 文件内的数据集读/写 任何 形状的双精度数组。为了实现这一点,我使用了一些 C 指针技巧,这样子例程只接受数组的第一个元素作为 val
,但它实际上使用临时缓冲区 buf(1:sz_buf)
读取/写入整个数组。
到目前为止,我对 read 子程序有以下内容(在删除错误检查以保持简洁之后):
SUBROUTINE hdf5_read_array_d( fname,path,name,val,dims )
USE ISO_C_BINDING,ONLY: C_SIZE_T,C_LOC,C_F_POINTER
! Input arguments
CHARACTER(LEN=*),INTENT(IN) :: fname,name
REAL(KIND(1.D0)),TARGET,INTENT(OUT) :: val
INTEGER,DIMENSION(:),INTENT(IN) :: dims
! Internal variables
INTEGER(KIND=HID_T) :: h5root,h5path,h5dset
INTEGER(KIND=HSIZE_T),DIMENSION(SIZE(dims)) :: h5dims
REAL(KIND(1.D0)),POINTER :: buf
INTEGER(KIND=C_SIZE_T) :: sz_buf
INTEGER :: dim
! Open the file in read-only mode
CALL h5fopen_f( TRIM(fname),H5F_ACC_RDONLY_F,h5root,ierr )
! Open the pre-existing path in the file as a group
CALL h5gopen_f( h5root,TRIM(path),ierr )
! Open the dataset
CALL h5dopen_f( h5path,TRIM(name),h5dset,ierr )
! Convert dims to HSIZE_T
h5dims(:) = dims(:)
! C pointer trickery: cast double -> void* -> double*
sz_buf = PRODUCT(dims)
ALLOCATE( buf( sz_buf ) )
CALL C_F_POINTER( C_LOC(val),buf,(/sz_buf/) )
! Read data from dataset through buffer
CALL h5dread_f( h5dset,H5T_NATIVE_DOUBLE,h5dims,ierr )
! Clean up and close HDF5 file
NULLIFY(buf)
CALL h5dclose_f( h5dset,ierr )
CALL h5gclose_f( h5path,ierr )
CALL h5fclose_f( h5root,ierr )
RETURN
END SUBROUTINE hdf5_read_array_d
现在,问题是,除了/代替DEALLOCATE(buf)
之外,我还需要放入NULLIFY(buf)
吗?
任何帮助将不胜感激。
注意:我知道 Fortran 2018 包含假定秩数组 val(..)
可以优雅地解决这个问题。但同样,这是一个较新的功能,可能尚未被所有编译器实现。
编辑:在 C_F_POINTER()
上,这是 Metcalf、Reid 和 Cohen(第 4 版,不是包含 Fortran 2018 内容的最新版本)的屏幕截图:
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)