在 C/C++ 应用程序中使用 Fortran90 模块

Using a Fortran90 module in a C/C++ application

本文关键字:Fortran90 模块 应用程序 C++      更新时间:2023-10-16

我有一个用fortran90编写的大模块的源文件,其中包含一些类型定义,一些接口,一些函数和子例程。我能够编译它并在普通fortran程序中使用它。

但是由于我一直使用C/C++并且我对fortran了解不多,因此我想在C/C++程序中使用此模块。这是使用其数据类型并在其上调用其函数/子例程。

可能吗?我该怎么做?我必须实现哪些步骤?网络上是否有一些详尽的教程(我没有通过简短的谷歌搜索找到这么多......

Fortran 2003 添加了与 C 语言互操作性的具体规定。 您可以在 GCC 文档中找到简要说明。 但是,如果您的Fortran代码不使用这些功能(实际上它可能没有),并且您不准备对其进行修改,那么答案在很大程度上取决于您的Fortran和C工具链。 涉及的一些问题包括

  • 名称重整。 许多 Fortran 编译器隐式向声明的函数名称添加一个或多个下划线,并且大多数将标识符转换为全小写或全大写
  • 数组索引。 Fortran 数组索引从 1 开始(默认情况下),多维数组的索引顺序与 C 使用的顺序相反。
  • 字符串参数。 Fortran 具有显式长度的字符串。 它们在函数的参数列表中的表示方式因编译器而异。 大多数使用char *并将长度作为单独的参数传递,但也采用了其他安排。 此外,长度参数可以紧跟在指针之后,也可以追加在参数列表的末尾。
  • 字符串一般。 Fortran 具有显式长度的字符串。 超过有效数据末尾的仓位应为空白填充。
  • 指针。 Fortran 95 没有原始指针。 它确实有一个名为指针的东西,但它并不直接类似于 C 指针。
  • 标量数据类型。 从 C 数据类型(如 intdouble)到 Fortran 数据类型的映射在某种程度上取决于所涉及的编译器。 不能保证一个编译器提供的所有类型在另一个编译器已知的类型中具有类似的类型。
  • 用户定义类型。 如果没有 C 互操作功能,即使可以正确匹配组件的类型,也很难确保用户定义类型的布局相同。
  • 参数传递约定。 除了 Fortran 使用引用调用之外,Fortran 90 还提供了数组传递模式,这些模式不会映射到 C 中的任何内容。 并非所有函数都使用这些模式来传递数组,但您不太可能调用这样做的函数(F03 的 C 互操作功能甚至不支持它们)。
  • 不要将 Fortran 外部 I/O 与 C 外部 I/O 混合使用。 很难做到正确。
  • 您可能需要链接 Fortran 运行时库。 它的名称因编译器而异。

这不是一个详尽的列表,但它涵盖了大多数常见问题。 您需要处理其中的哪一个取决于您尝试连接的包。

在 F03 之前,Fortran/C 互操作通常是在逐个产品、特定于工具链的基础上提供的。 通常在一侧或另一侧或两者上提供一组特定的接口功能。 仍然有很多这样的代码,这对你来说可能也是一个不错的策略。 此外,还有一些工具试图帮助解决混乱。 例如,GNU Autotools对它有一些支持,涵盖的不仅仅是GNU工具链。 或者,您可能需要检查某些对象文件以确定如何处理其中一些问题。

来自 c 的搜索调用 fortran 给了我几个指向各种教程和示例的链接。

一些亮点:

Fortran 调用是通过引用进行的,因此您可以大量使用指针/地址运算符。

Fortran 例程通常通过一些简单的名称重整导出。您可以通过阅读手册找到答案,也可以使用 nm f.o ,其中 f.o 是一个编译的 fortran 文件。

使用获取的例程名称,您需要创建一个 C 头文件,其中包含要调用的例程的声明。

链接时,您需要与 fortran 库链接,-l<name of fortran lib> .