在启动时执行fortran代码?

时间:2016-07-22 09:40:33

标签: initialization fortran

启动时是否可以使用fortran执行代码,而无需将其明确地放入主程序中?

USECASE

考虑例如从具有关键字 - 值对的配置文件中读取数据的例程,用于不同的模块。

为了代码局部性,有效的关键字以及无效值的错误处理在需要数据的模块中定义是有利的。

现在,实现这种行为的唯一模式,我能想到的,就是在所述模块中编写一个设置子程序,由主程序调用。

这意味着更改模块的逻辑可能需要更改主程序。这似乎比例如难以维持在Python中做类似

的事情
# ------ ./project/module.py ------
from project.config import register_keyword
register_keyword("some_setting")

2 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是使用派生类型构造函数:

module foo

  implicit none

  ! only export the derived type, and not any of the
  ! helper procedures
  private
  public :: mytype

  type :: mytype
    ! internals of type
  end type

  ! Write an interface overloading 'mytype' allows us to
  ! overload the type constructor
  interface mytype
    procedure :: new_mytype
  end interface mytype

contains

  type(mytype) function new_mytype(setting)
    ! Some generic setting type
    type(setting_type), intent(in) :: setting

    ! do something with setting
    ...
  end function new_mytype

end module foo
program bar

  use foo

  implicit none

  type(mytype) :: thing
  type(setting_type) :: setting

  ! calls 'foo::new_mytype'
  ! all implementation details hidden away
  thing = mytype(setting)

end program bar

答案 1 :(得分:0)

据我所知,根据Fortran (2003) standard,这是不可能的。

register_keyword这样的“静态”函数调用必须在模块定义的specification-part中完成。根据一般定义,此specification-part可能包含stmt-function-stmt,但在C1105中明确禁止这样做:“......不得包含stmt-function-stmt,[...]” 。所以你基本上只会调用内在函数。

如果你真的不想编辑你的主程序,但你可以使用额外的C ++中间文件,那么下面的PoC可以工作:

prog.f03

program main

end program

my_module.f03

module my_mod
   use, intrinsic :: iso_c_binding
   contains
      function foo() bind(C, name="foo")
         integer(c_int) :: foo

         write (*,*) "hello, world!"
         foo = 10
      end function
end module

my_module.cc

extern "C" int foo();
int a = foo();

编译并链接如下:

g++ -Wall -c my_module.cc -o my_module.o
gfortran -Wall -o prog prog.f03 my_module.f03 my_module.o

尽管Fortran程序为空,但仍会有输出:

 hello, world!

我仍然不建议这样做,因为当C / C ++全局/静态函数调用发生时,可能无法保证Fortran RT环境已准备就绪。