启动时是否可以使用fortran执行代码,而无需将其明确地放入主程序中?
考虑例如从具有关键字 - 值对的配置文件中读取数据的例程,用于不同的模块。
为了代码局部性,有效的关键字以及无效值的错误处理在需要数据的模块中定义是有利的。
现在,实现这种行为的唯一模式,我能想到的,就是在所述模块中编写一个设置子程序,由主程序调用。
这意味着更改模块的逻辑可能需要更改主程序。这似乎比例如难以维持在Python中做类似
的事情# ------ ./project/module.py ------
from project.config import register_keyword
register_keyword("some_setting")
答案 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环境已准备就绪。