“C 指针技巧”允许不匹配的 Fortran 数组等级

问题描述

我正在编写一个 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 内容的最新版本)的屏幕截图:

Metcalf_et_al_C_F_POINTER

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)