在 C/C++ 应用程序中使用 Fortran90 模块
Using a Fortran90 module in a C/C++ application
我有一个用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 数据类型(如
int
和double
)到 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>
.
- 尝试导入pybind-opencv模块时出现libgtk错误
- 为什么当我解模块化时,这个C++代代码"效率较低"?
- 如果C++对象的类在另一个boost模块中声明,如何使用boost将指向该对象的指针返回到python
- 内联如何影响模块接口中的成员函数
- C++返回 Numpy 数组的 Python 扩展模块
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 如何从线程中的不同模块调用函数?
- 如何使用 soong 命名空间来有条件地编译模块
- asn1c 不会从 asn.1 模块中提取八位字节字符串的默认值
- CMake - 模块 + 库混淆
- 特征 LLT 模块给出不正确的结果?
- 枚举进程模块在有效句柄上返回无效句柄
- 在 python 模块中导入子模块时PyImport_Import失败
- 将 PCL 链接到 Cython C++ 模块
- 即使直接从官方示例中复制,也找不到未知类型名称QML_ELEMENT和 QML 模块
- 电源功能模块化操作
- 如何告诉本机节点模块所需的dll存储在哪里?
- 如何为模块化应用程序实现C++插件系统
- C++ Python 模块在 Blender 中崩溃,但在 Python 控制台中不会崩溃
- 在 C/C++ 应用程序中使用 Fortran90 模块