Interface 如何在Fortran接口中使用用户定义的类型

Interface 如何在Fortran接口中使用用户定义的类型,interface,fortran,user-defined-types,Interface,Fortran,User Defined Types,在Fortran 2003模块中,我定义了一个名为t_savepoint的类型,稍后,我想为名为fs_initializesavepoint的子例程定义一个接口,该子例程将t_savepoint类型的对象作为唯一参数 以下是整个模块的代码: module m_serialization implicit none type :: t_savepoint integer :: savepoint_index real :: savepoin

在Fortran 2003模块中,我定义了一个名为
t_savepoint
的类型,稍后,我想为名为
fs_initializesavepoint
的子例程定义一个接口,该子例程将
t_savepoint
类型的对象作为唯一参数

以下是整个模块的代码:

module m_serialization

    implicit none

    type :: t_savepoint
        integer :: savepoint_index
        real    :: savepoint_value
    end type t_savepoint

    interface

        subroutine fs_initializesavepoint(savepoint)
            type(t_savepoint) :: savepoint
        end subroutine fs_initializesavepoint


    end interface

end module m_serialization
我想要这样一个接口的原因是,稍后我将使这个fortran模块与C进行互操作

如果我尝试编译它(gfortran-4.7.0),我会收到以下错误消息:

            type(t_savepoint) :: savepoint
                                          1
Error: The type of 'savepoint' at (1) has not been declared within the interface
如果我在子例程中移动类型的定义,错误就会消失;但是如果我想在许多子例程中使用相同的类型,我应该在所有子例程中重复定义吗

先谢谢你


编辑:解决方案是将类型的定义移动到另一个模块上,然后在每个子例程中使用它。但是,我不太喜欢这个解决方案,因为类型
t\u保存点
和子例程是同一概念主题的一部分。

在接口块中,您没有通过主机关联访问环境的权限。要解决此问题,您需要精确导入数据类型:

[luser@cromer stackoverflow]$ cat type.f90
module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

  interface

     subroutine fs_initializesavepoint(savepoint)
       Import :: t_savepoint
       type(t_savepoint) :: savepoint
     end subroutine fs_initializesavepoint


  end interface

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90
这里是f2003

然而,我怀疑你的表达方式表明你并没有用最好的方式编写代码。更好的方法是简单地将例程本身放入模块中。那么,您根本不需要为界面操心:

module m_serialization

  implicit none

  type :: t_savepoint
     integer :: savepoint_index
     real    :: savepoint_value
  end type t_savepoint

Contains

  Subroutine fs_initializesavepoint(savepoint)

    type(t_savepoint) :: savepoint 

    Write( *, * ) savepoint%savepoint_index, savepoint%savepoint_value

  End Subroutine fs_initializesavepoint

end module m_serialization
[luser@cromer stackoverflow]$ gfortran -c type.f90

考虑到模块的设计实际上是为了处理连接的实体,这确实是用Fortran实现的方法。它还具有只需要f95编译器的优点,因此是普遍可用的(尽管必须承认,通常会实现导入)

非常感谢您,Ian!进口声明解决了我的问题。也谢谢你的进一步评论。无论如何,请让我解释一下,我需要的正是第一个版本,因为我不会用Fortran实现子例程,而是用C实现。因此,我只需要一个可用于语法检查的接口。我也在使用C互操作性功能,所以我需要F2003。另外,除非类型具有BIND(C)或是序列类型,否则如果你“重复定义”一个类型,你实际上会声明一个全新的类型(即使它具有相同的名称和相同的组件等)。当编译器根据伪声明检查实际参数的类型时,这将导致(混淆)错误。因此,对于非绑定(C)、非序列类型,必须使用“其他模块”解决方案(F95)或Ian Bush描述的F2003导入语句。