c++ - 从 FORTRAN 代码调用的 C++ 函数调用 C++ 函数

标签 c++ makefile fortran fortran90

我正在尝试将一些数据从 FORTRAN (f90) 代码发送到 C++ 函数。简化的工作代码如下所示: ma​​in.f90:

  program test
  !
     integer:: ii, jj, kk
     common/ijk/ ii, jj, kk
     character*32 cc
     ii = 2
     jj = 3
     kk = 4
     cc = 'Example of a character string'
  !
     call doubleIJK(cc)
  !
     write(*,*) ii, jj, kk
  !
  end program test

func.cpp:

  #ifdef __cplusplus
     extern"C" {
  #endif

  #include <stdio.h>

  extern struct
  {
     int ii, jj, kk;
  } ijk_;

  void *__gxx_personality_v0;

  int doubleijk_(char *cc, int ll)
  {
     cc[ll--] = '\0';  // NULL terminate the string
     printf("From doubleIJK: %s\n",cc);
     ijk_.ii *=2;
     ijk_.jj *=2;
     ijk_.kk *=2;
     return(1);
  }

  #ifdef __cplusplus
     }
  #endif

和我的Makefile:

  # Compilers
  FORTRAN_COMPILER = ifort
  CPP_COMPILER = g++

  # Flags
  CPP_FLAG = -c #-lstdc++
  FORTRAN_FLAG = -o

  # Rules:
  test.exe: main.o func.o
      $(FORTRAN_COMPILER) $(FORTRAN_FLAG) test.exe main.o func.o

  # Objects
  func.o: func.cpp
      ($(CPP_COMPILER) $(CPP_FLAG) func.cpp)

  main.o: main.f90
      ($(FORTRAN_COMPILER) $(CPP_FLAG) main.f90)

========================================

接下来,我想调用另一个cpp 函数对我现在在func.cpp 中的数据进行一些操作。一个过于简化的版本看起来像: addition.cpp:

  #include <iostream>
  #include "addition.h"

  using namespace std;

  int addition (int a, int b)
  {
    int r;
    r = a + b;
    cout << r << endl;
    return r;
  }

addition.h:

  #ifndef ADDITION_H
  #define   ADDITION_H
  int addition (int a, int b);
  #endif /* ADDITION_H */

更新后的Makefile:

# Compilers
FORTRAN_COMPILER = ifort
CPP_COMPILER = g++

# Flags
CPP_FLAG = -c #-lstdc++
FORTRAN_FLAG = -o

# Rules:
test.exe: main.o func.o addition.o
   $(FORTRAN_COMPILER) $(FORTRAN_FLAG) test.exe main.o func.o addition.o

# Objects
func.o: func.cpp
    ($(CPP_COMPILER) $(CPP_FLAG) func.cpp)

addition.o: addition.cpp
   ($(CPP_COMPILER) $(CPP_FLAG) addition.cpp)

main.o: main.f90
   ($(FORTRAN_COMPILER) $(CPP_FLAG) main.f90)

我还将 func.cpp 更新为:

  #ifdef __cplusplus
     extern"C" {
  #endif

  #include <stdio.h>
  #include "addition.h"

  extern struct
  {
     int ii, jj, kk;
  } ijk_;

  void *__gxx_personality_v0;

  int doubleijk_(char *cc, int ll)
  {
     cc[ll--] = '\0';  // NULL terminate the string
     printf("From doubleIJK: %s\n",cc);
     ijk_.ii *=2;
     ijk_.jj *=2;
     ijk_.kk *=2;

     int z;
     z = addition (5,3);

     return(1);
  }

  #ifdef __cplusplus
     }
  #endif

我无法编译代码。我不确定,但我猜 makefile 有问题,因为每次我更改目标文件的顺序时,我都会收到不同的错误,例如:

  /tmp/cc4AuTkF.o(.text+0x50): In function `doubleijk_':
  : undefined reference to `ijk_'
  /tmp/cc4AuTkF.o(.text+0x58): more undefined references to `ijk_' follow
  collect2: ld returned 1 exit status
  make: *** [func.o] Error 1

  func.o(.text+0x67): In function `doubleijk_':
  : undefined reference to `addition'
  addition.o(.text+0x23): In function `__static_initialization_and_destruction_0(int, int)':
  : undefined reference to `std::ios_base::Init::Init()'
  addition.o(.text+0x28): In function `__static_initialization_and_destruction_0(int, int)':
  : undefined reference to `std::ios_base::Init::~Init()'
  addition.o(.text+0x6f): In function `addition(int, int)':
  : undefined reference to `std::cout'

如果能就此问题提供任何帮助,我将不胜感激。

最佳答案

正如评论所建议的那样,在与 Fortran 编译器链接时为 C++ 添加正确的运行时库

FORTRAN_FLAG = -lstdc++ -o

有了 GCC,你甚至可以做到

gfortran *.cpp *.f90 -lstdc++ -o test.exe

您还可以链接 C++ 编译器并将 Fortran 库添加到链接命令。

请注意,您的代码中的任何地方都没有 iso_c_binding,即使您使用了标签并在标题中引用了它。它是连接 C 和 Fortran 的现代方式。如果您想了解更多关于现代方法的信息,请阅读标记维基页面。

关于c++ - 从 FORTRAN 代码调用的 C++ 函数调用 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25127493/

相关文章:

c++ - 构建包时出现 Cmake 错误

fortran - 编译 Fortran 是否需要接口(interface) block ?

模块 use 语句中的 Fortran 内在关键字

c++ - 为什么我不能分配给 uint_8[] 类型的 unique_ptr?

c++ - Divide et impera sum of the elements of an array 错误

c++ - 使用cmake构建静态库的静态库

makefile - 传递参数以在 Makefile 中进行调用

c - 目标文件位于单独目录中的简单非递归 Makefile

algorithm - Fortran 冒泡排序算法

c++ - static_message 或类似的东西