Spi*_*ros 4 fortran interface user-defined-types
在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
Run Code Online (Sandbox Code Playgroud)
我想要这样一个接口的原因是,稍后我将使这个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
Run Code Online (Sandbox Code Playgroud)
如果我在子程序中移动类型的定义,则错误消失; 但如果那时我想在许多子程序中使用相同的类型,我应该在所有子程序中重复定义吗?
先感谢您.
编辑:解决方案是将类型的定义移动到另一个模块,然后use在每个子例程中移动到它.但是我不太喜欢这个解决方案,因为类型t_savepoint和子例程是同一个概念主题的一部分.
在接口块中是正确还是错误,您无法通过主机关联访问环境.要解决此问题,您需要显式导入数据类型:
[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
Run Code Online (Sandbox Code Playgroud)
这是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
Run Code Online (Sandbox Code Playgroud)
鉴于模块实际上是为处理连接实体而设计的,这实际上是在Fortran中实现它的方法.它还具有仅需要f95编译器的优点,因此普遍可用(尽管通常可以实现导入)