1

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

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

4

3 回答 3

2

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

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

于 2013-09-07T07:46:03.487 回答
1

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

于 2013-09-10T02:57:03.100 回答
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

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

于 2013-09-06T17:43:12.660 回答