【问题标题】:How to link a fortran subroutine to a cpp main program?如何将 fortran 子例程链接到 cpp 主程序?
【发布时间】:2013-09-06 17:01:04
【问题描述】:

我正在尝试编译一个 c++ 程序,但它不起作用。 首先,我应该说 c++ 不是我真正了解的语言,我使用 Fortran。无论如何,主 c++ 程序调用一个 fortran 子例程。我可以编译这个子例程,但是当我想编译 c++ 程序时,会出现链接错误。 真正的程序很大,调用了很多子程序,所以我做了一个简单的测试(简单的程序只调用了一个子程序),它也不能正常工作!当我想创建 .x 时,我的子程序是未定义的。 这是c++程序(test-TQINIT.cpp)和子程序(TQINIT.f)。

测试-TQINIT.cpp:

  #include <iostream>

  using namespace std;

  extern "C"
  {
  void  TQINIT_(int*, int*);
  }

  main()
  { int NWG;
        NWG=80000;
    int *IWSG = new int[NWG];
 TQINIT_(IWSG,&NWG);
  }

TQINIT.f:

  SUBROUTINE TQINIT(IWSG,NWG)
  IMPLICIT NONE

  INTEGER NWG
  INTEGER IWSG(NWG)
  LOGICAL TQG2ERR
  INTEGER IERR

  CALL TQRSERR

  CALL TQINI(NWG,IWSG)

  IF (TQG2ERR(IERR)) THEN
    WRITE(6,*)'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    WRITE(6,*)'ERROR INITIALIZING (TQINIT) !!!'
    WRITE(6,*)'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
    STOP
  ENDIF

  END

我使用以下代码编译子例程:

  gfortran -c TQINIT.f 

并获得一个 TQINIT.o

然后我编译主程序使用:

  g++ -c test-TQINIT.cpp 

并获得一个 test-TQINIT.o。

然后创建我使用的 .x(TQINIT.f 需要库):

  g++ test-TQINIT.o TQINIT.o -L/usr/local/thermocalc/3.0/SDK/TQ8 -ltq-linux-x86_64-gfortran44-8 -o test-TQINIT.x

这是我得到的:

  test-TQINIT.o: In function `main':
  test-TQINIT.cpp:(.text+0x33): undefined reference to `TQINIT_'
  collect2: ld returned 1 exit status

我希望有人能够帮助我。 提前谢谢你。

【问题讨论】:

  • 目标文件中子程序的名字可能是tqinit_而不是TQINIT_,所以你在C++中的调用应该是小写的。
  • 您可能应该将其发布为答案。即使您不关心分数,未来的访问者也可以更轻松地寻找得到支持和接受的答案。
  • 这是最近一个问题的重复:stackoverflow.com/questions/18491911/…

标签: c++ fortran subroutine


【解决方案1】:

Fortran 不区分大小写,并且目标文件中的子例程名称通常(据我所知)以小写字母结尾并带有下划线,因此您的名称可能命名为 tqinit_ 而不是 TQINIT_,所以你在 C++ 中的调用应该是小写的。

您可以使用 Alexander Vogt 的答案中给出的objdump -t TQINIT.o 命令验证目标文件中的名称,或者更简洁的nm TQINIT.o

【讨论】:

  • 我已经使用小写更改了所有子程序调用,它完美地工作。非常感谢 steabert。
【解决方案2】:

如果您在 Fortran 中使用 ISO_C_BINDING,您将可以控制其他语言将看到的精确例程名称,例如,大小写、无下划线。您还可以声明参数,以保证与 C/C++ 的一致性。有关此主题的更多信息,请参阅https://stackoverflow.com/questions/tagged/fortran-iso-c-binding

【讨论】:

    【解决方案3】:

    我不是混合 C 和 Fortran 方面的专家,但我一直使用直接链接 Fortran 代码

    g++ test-TQINIT.cpp TQINIT.o -L/usr/local/thermocalc/3.0/SDK/TQ8 \
        -ltq-linux-x86_64-gfortran44-8 -o test-TQINIT.x
    

    而不是分别编译这两个文件然后链接...也许这会有所帮助(尽管您的方式应该也可以,但至少在我尝试的简单示例中可以)。

    顺便说一句: 您可以通过发出来了解如何调用 Fortran 对象中的函数

    objdump -t TQINIT.o
    

    这应该会给你正确的函数名来调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 2018-01-21
      • 1970-01-01
      • 2011-11-10
      • 1970-01-01
      相关资源
      最近更新 更多