如何将fortran子例程链接到c ++主程序?

时间:2013-09-06 17:01:05

标签: c++ fortran subroutine

我正在尝试编译一个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 

并获得测试-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

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

4 个答案:

答案 0 :(得分:2)

Fortran是不区分大小写的,并且目标文件中的子例程的名称通常(据我所知)最后用小写字母结尾,因此你的名字可能是tqinit_而不是{{1所以你在C ++中的调用应该是小写的。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

我不是混合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

这应该为您提供正确的函数名称来调用。

答案 3 :(得分:0)

正如Steabert所提出的,将大写改为小写已解决了链接问题。 感谢大家的帮助。