【问题标题】:Calling Fortran subroutine from C++ using Intel compilers使用 Intel 编译器从 C++ 调用 Fortran 子例程
【发布时间】:2012-05-03 14:27:29
【问题描述】:

我需要在 C++ 代码中调用 Fortran 程序。该程序使用 Intel 编译器进行编译 Fortran 程序跨越多个文件,过去被称为 PROGRAM。我试图做的是将主程序调用更改为名为 SIMULATOR 的子程序。然后,我将每个 Fortran 源代码编译为目标文件,而不将它们全部放入可执行文件中。然后,我准备用一个简单的 C++ 包装器将所有 Fortran 对象链接起来进行测试。代码和makefile如下。

包装器.cpp:

#include <iostream.h>

using namespace std;

extern "C"{
void simulator_();
}

int main()
{
    cout << "starting..." << endl;
    simulator_();
    cout << "success!" << endl;
    return 0;
}

生成文件:

all:
    ifort -nologo -O3 -cxxlib -nofor-main -gen-interfaces -traceback -check bounds -save -static -threads -c modules.for
    ifort -nologo -O3 -cxxlib -nofor-main -gen-interfaces -traceback -check bounds -save -static -threads -c Finterp.for
--a few more sources go here--
    ifort -nologo -O3 -cxxlib -nofor-main -gen-interfaces -traceback -check bounds -save -static -threads -c Simsys.for
    icpc -c wrapper.cpp
    icpc -o cppprogram *.o

这是编译器的(部分)输出。 Simsys 是包含我试图调用的模拟器函数的文件:

Simsys.o: In function `simsys_':
Simsys.for:(.text+0xed4): undefined reference to `for_write_int_lis'
Simsys.for:(.text+0xeef): undefined reference to `for_adjustl'
Simsys.for:(.text+0xf38): undefined reference to `for_trim'
Simsys.for:(.text+0xf83): undefined reference to `for_concat'
Simsys.for:(.text+0x1071): undefined reference to `for_open'
Simsys.for:(.text+0x131d): undefined reference to `for_emit_diagnostic'
Simsys.o:Simsys.for:(.text+0x1670): more undefined references to `for_emit_diagnostic' follow

现在根据一个有类似问题的人(http://www.velocityreviews.com/forums/t288905-intel-compiler-8-1-c-calling-fortran-routine.html),好像我我错过了一些图书馆。那个人写道,他们包含了一个特定的库,它帮助了他们,但我不知道如何开始寻找我需要的库。我也不知道如何在我正在使用的 HPC 系统上找到英特尔编译器的路径,所以我希望能在正确的方向上提供一些帮助。在尝试将 fortran 程序与 C++ 链接之前,我不需要做任何特别的事情来编译它,所以我有点卡在思考从这里开始的地方。

顺便说一句,Fortran 程序不需要任何输入,它都是自包含的。

提前感谢您的帮助和见解!

编辑:

ifort 给了我: /usr/global/intel/Compiler/11.1/073/bin/intel64/ifort

尝试使用 ifort 完成最终链接后,出现以下错误:

ld: 找不到 -lunwind

我找到了有关 unwind 的文档 (https://savannah.nongnu.org/news/?group=libunwind),但我没有尝试自己调用这个库,也不知道它来自哪里。

【问题讨论】:

  • 这只是一个有根据的猜测,但我认为您需要链接的库称为 dforrt.dll 或 forrt.dll 或类似的名称。
  • which iforttype ifort 应该告诉你编译器的路径。 (虽然这可能对你没有帮助。)
  • @sarnold 已编辑以显示它所说的内容。
  • 将fortran代码链接为dll,然后调用它

标签: c++ fortran


【解决方案1】:

简单的方法是使用 ifort 进行链接,以获取 Fortran 运行时库。一些说明在http://www.ualberta.ca/AICT/RESEARCH/LinuxClusters/doc/ifc91/main_for/mergedProjects/bldaps_for/pgsclmix.htm

如果您在 Fortran 端使用 ISO_C_Binding,您可以控制例程的名称并去掉下划线。微不足道...如果您开始在 C/C++ 和 Fortran 之间添加参数,ISO C 绑定将变得更加有用。

【讨论】:

  • 这看起来是朝着正确方向迈出的一步,但现在我有了:ld: 找不到 -lunwind。我查找了有关此问题的 stackoverflow 线程(stackoverflow.com/questions/335928/…),但我很困惑,因为我从未明确尝试过自己调用 -lunwind..
  • 猜猜,回溯选项可能需要 libunwind 吗?尝试删除该选项。尝试查找 libunwind 在您的系统上的位置,并在链接命令上使用 -L 选项添加该目录。您是否包含 cxxlib-icc 和 nofor_main 选项?
  • 更具体地说,仅供以后阅读本文的人使用...我删除了回溯选项,并且不再出现展开错误。
【解决方案2】:

编译/链接 fortran 和 C++ 是完全可行的,但有一些细节需要解决。英特尔有帮助地在线提供他们的文档: http://software.intel.com/en-us/articles/intel-fortran-composer-xe-documentation/

请参阅英特尔 Fortran 编译器用户/参考指南,特别是“编译器参考”/“混合语言编程”/“Fortran/C 混合语言程序”部分。 “编译器参考”/“库”部分也很有用。

最后,您需要在链接行中包含一些 fortran 静态库,并且您可能需要在您的应用程序中重新分发一些 fortran 运行时 dll。

【讨论】:

    猜你喜欢
    • 2014-01-14
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    相关资源
    最近更新 更多