提问人:DJames 提问时间:6/1/2023 最后编辑:Vladimir F Героям славаDJames 更新时间:6/1/2023 访问量:108
可以从 C 调用 f77 子程序吗?
Can an f77 subroutine be called from C?
问:
在现代 Fortran 中,我们可以使用 C 绑定从 C 调用子例程。例如,Fortran 子例程将如下所示
subroutine my_routine(...) bind (C, name="my_routine")
但是,如果 fortran 子例程是旧的 f77 子例程,则此绑定可能不是可用的解决方案。最好的选择是什么?
答:
但是,如果 fortran 子例程是旧的 f77 子例程,则此绑定可能不是可用的解决方案。
这要视情况而定。Modern Fortran 在很大程度上向后兼容 Fortran 77。你的 F77 子例程不会附带属性,但如果你愿意添加一个属性并使用现代 Fortran 编译器编译它,那么它很有可能像你最初为较新的 Fortran 版本编写的代码一样工作。bind
另一方面,C 互操作给 Fortran 带来的是标准化,而不是新功能。人们几乎在使用 C 语言时就一直在用 C 语言调用 Fortran 例程。
这里的问题是细节取决于系统和编译器。如果您不依赖 C 互操作,则需要适应 Fortran 编译器的名称修改和参数传递约定,以便从 C 代码成功调用 Fortran 编译的函数。这些各不相同。过去有相当多的工具和文档可用于此类活动。我想现在更难找到,但其中大部分应该仍然有效。
最好的选择是什么?
这取决于您的具体限制。如果您准备修改 Fortran 源代码并使用现代编译器进行编译,那么我至少会从向函数添加一个属性开始,看看效果如何。bind
评论
bind(C)
请记住,如果您使用任何相当新的编译器,您可能无论如何都将代码编译为 Fortran 2003-2018。即使是像 g95 这样停产的编译器也已经有了 Fortran 2003 的 C-Fortran 互操作。
但是,正如我在 John 的回答中评论的那样,如果您确实添加了它,则对子例程的现有 Fortran 调用(作为没有显式接口的外部子例程)将无效。例如,它们可能在实践中有效,但不适用于字符串。即使它们能起作用,它们也不会符合标准。仅当您关心 Fortran 对子例程的现有调用时,这才重要。bind(C)
如果您根本无法触摸代码 - 如果源代码由于某种原因必须保持完整。您始终可以编写一个包装子例程,该子例程使用并调用原始子例程。通常这不是不必要的,但这是一种可能性。bind(C)
正如 John Bollinger 所提到的,有一些方法可以在不以系统特定的方式调用 Fortran 子程序,这在本网站的几个问题中进行了讨论。符号名称通常带有下划线(最有可能)或前缀,或两者兼而有之。两个下划线也是一种可能性。符号名称可以使用小写字母或大写字母。参数将通过引用(通过指针)传递。字符串将使用包含每个字符串长度的隐藏整数参数。bind(C)
character(*)
评论