【问题标题】:Mixed Programming Fortran and C混合编程 Fortran 和 C
【发布时间】:2011-10-12 17:06:06
【问题描述】:

我是一名理论物理学研究生,从事宇宙学研究。在我的研究过程中,我使用了相当庞大的 Fortran 代码库,并且我使用 C 来满足我的编程需求。

我已经能够在大量测试文件中链接这两个程序,它们运行良好。但对他们来说,我一直在使用目标文件来链接它们。但是当我试图通过 C 运行真正的交易时,包括对 Fortran 头文件的引用。它们似乎可以很好地集成和相互调用,但是 Fortran 头文件的格式与 C 编译器不兼容,因此当它跳转到头文件时,它开始抛出无法理解语法的错误。

例如,Fortran 头文件使用 real*8 定义双变量,因此当 C 读取它们时会抛出错误。文件中的 cmets 也会发生同样的情况。

所以,我想问有没有什么办法可以解决这个问题?即通过 C 使 fortran 格式的头文件可读。

我浏览了互联网,发现了令人困惑的答案,我不知道该遵循哪一个。对此问题的任何帮助将不胜感激:)

【问题讨论】:

  • 什么版本的 Fortran?如果是 Fortran 77,你可以使用 f2c。
  • 我真的很困惑什么不适合你。在 c 和 fortran 位分别编译后链接目标文件在单个项目中结合 c 和 fortran 的方式。您在寻找自动标题翻译器吗?

标签: c fortran mixed fortran-iso-c-binding


【解决方案1】:

抱歉,您很困惑。什么是 Fortran 头文件?例如,您无法使用 C 编译器读取 Fortran 包含文件!两种语言差别太大。此外,Fortran 包含文件几乎从来都不是与 C 相比的头文件。

我不知道您使用的是哪种编译器。但是,如果您选择了最新的 GCC 版本(Gnu Compiler Collection),那么其中包含的 Fortran 编译器能够考虑 ISO_C_BINDING 功能,这使得 Fortran-C 的耦合更加容易。

例子:

MODULE my_fortran
  USE iso_c_binding
  IMPLICIT NONE
  CONTAINS
  SUBROUTINE my_subroutine(a,b) BIND(C,name="my_sub")
    INTEGER(c_int),INTENT(in),VALUE :: a
    REAL(C_DOUBLE),INTENT(out) :: b
    ...
  END SUBROUTINE
END MODULE

例如名为“my_sub.h”的C头文件:

void my_sub(int, double *);

C 文件

#include "my_sub.h"

int main(){
  double b;
  int a=3;
  my_sub(a,&b);
  ...
}

【讨论】:

  • "什么是 Fortran 头文件?" 在过去的糟糕时期,将 COMMON 块声明放在单独的文件中并不罕见(通常带有 @987654325 @ 结尾,然后是多个文件的INCLUDEd。当有人在 FORTRAN 上下文中说“标题”时,就是这么想的。当然,我不能代表其他任何人。
  • fortran 头文件是指带有 *.h 扩展名的文件,其中包含头文件的段。例如,下面是用fortran编写的头文件的代码,*** c---------------------------- ------------------------------------------c c 源自 dssusy.h 2008- 01-22, paolo gondolo * 有用的全局变量 real*8 pi real*8 gev2cm3s !添加者 /tb common /ruse​​ful/ pi, gev2cm3s c save common blocks save /ruse​​ful/
  • 再次请不要将 Fortran 包含文件包含到 C 文件中!绝不 !这行不通。 Fortran 包含文件必须仅包含在 Fortran 源文件中。
  • 那么,你的问题是你的c编译器不会处理fortran,对吧?嗯,是的。 c 编译器和 fortran 编译器是不同的东西因为它们接受不同的语言。 (请注意,c 头文件的 .h 结尾纯粹是一种人类约定,编译器对此一无所知……给文件一个 .h 结尾并不意味着 c 编译器能够神奇地对其进行正面或反面) 也许您想要一个可以准备描述 fortran 接口的 c 头文件的预处理阶段。 这是一个有趣的要求。唉,我不知道有什么工具可以做到这一点。
  • "但是 Fortran 头文件的格式与 C 编译器不兼容,因此当它跳转到头文件时,它开始抛出无法理解语法的错误。"是的,C 和 Fortran 是不同的语言,您不能期望 C 编译器能够理解 Fortran 源代码,反之亦然。如果你在 Fortran 中有一些变量声明并且 C 需要理解这些相同的变量,你将不得不在 C 中编写一个等效的声明。
【解决方案2】:

Fortran 通常通过引用传递其变量(传递指针)。 这意味着您必须在调用 C 程序中提供地址。

函数结果,可以按值传递,例如下面的 代码调用了一个名为“gamma”的 FORTRAN 函数:

double   x, y;
   ..................
   x = 2.0; 
   y = gamma_(&x) 

确保 调用程序中变量的大小与大小相同 在 Fortran 例程中:

float  --- REAL     (this is typical, but not always the case)
double --- REAL*8

Fortran 函数必须在 C 调用函数的开头声明:

extern void read_(int *small, float *medium, double *large);

注意我们必须将所有变量作为指针传递给 Fortran。虽然函数名在 Fortran 中不区分大小写,但在 C 声明中和调用时会增加一个下划线:

 read_(&small, &medium, &large);

Fortran函数接收变量如下:

SUBROUTINE READ(small,medium,large)

  INTEGER       small
  REAL          medium
  DOUBLE        large

这些变量的精确大小取决于您的系统架构(32 位与 64 位),因此您需要在您的系统上确认 C 和 Fortran 中的 int、float 和 double 之间的对应关系。

【讨论】:

  • 1) 我试图调用的代码不是函数而是例程。 2)解析include命令并尝试编译头文件时发生错误。
  • 嗨,我也明白。但是当编译器转到用 Fortran 编写的头文件但我使用 GCC C 编译时会出现问题。我可以尝试将 .h 文件转换为对象,但是有许多这样的文件具有复杂的依赖关系。我不认为这是一个很好的主意。这就是为什么我正在寻找替代品。
  • 用 gcc 编译你的 C 代码,用 gfortran 编译你的 Fortran 代码。与 gfortran 链接似乎可以处理任何运行时库问题
  • gfortran -o myprog myprog.o read.o, gcc -c myprog.c, gfortran -c read.f
  • 这里有很多这样的文件,它们具有复杂的依赖关系。我不认为这是一个很好的主意。这就是为什么我正在寻找替代品。 ——
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多