用于从 FORTRAN 代码调用的 C++ 函数调用 C++ 代码的 Cmake 配置文件

Posted

技术标签:

【中文标题】用于从 FORTRAN 代码调用的 C++ 函数调用 C++ 代码的 Cmake 配置文件【英文标题】:Cmake configutarion file for calling a C++ code from a C++ function called by a FORTRAN code 【发布时间】:2014-10-03 18:19:41 【问题描述】:

我一直在使用 FORTRAN 代码 main.f90 向 func.cpp 发送一个数组,该数组将调用 C++ 代码addition.cpp & addition.h。该代码在 CentOS 4 平台上正常运行,但是当我将其移至 CentOS 6 平台时,它给了我错误。我曾尝试在两台机器上使用相同版本的 gcc (4.3.0) 或在 CentOS 6 中使用较新版本的 4.4.7,但问题仍未解决。我将代码的过度简化版本附加为

main.f90:

 program main
   use iso_c_binding
   implicit none

   interface
      function func (a) bind (C, name="func")
         import
         integer(c_int):: func
         real(c_double), dimension(1:4), intent(in):: a
      end function func
   end interface

   real(c_double), dimension(1:4):: a = [ 2.3, 3.4, 4.5, 5.6 ]
   integer(c_int):: result
   result = func(a)
   write (*,*) result
end program main

func.cpp:

#include <iostream>
#include "addition.h"
using namespace std;

#ifdef __cplusplus
  extern"C" 
#endif

void *__gxx_personality_v0;

int func(double a[]) 
   int i;
   for(i=0; i<4; i++) 
       cout << a[i] << endl;
   
   int z;
   z = addition (5,3);
   cout << z << endl;
   return 0;


#ifdef __cplusplus
  
#endif

addition.cpp:

#include <iostream>
#include "addition.h"
using namespace std;
int addition (int a, int b)

 int r;
 r = a + b;
 return r;

addition.h:

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

CMakeLists.txt:

PROJECT(test)
cmake_minimum_required(VERSION 2.6)
enable_language(C Fortran)
# Setting the compilers
set (CMAKE_Fortran_COMPILER /usr/bin/gfortran)
set (CMAKE_CXX_COMPILER /usr/bin/g++)
# Setting the flags
set (CMAKE_CXX_FLAGS "-lgfortran")
set_source_files_properties(main.f90 func.cpp PROPERTIES COMPILE_FLAGS -c)
# Making the executable
ADD_EXECUTABLE(test.exe main.f90 func.cpp addition.cpp addition.h)

我现在得到的错误是:

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make[2]: *** [test.exe] Error 1
make[1]: *** [CMakeFiles/test.exe.dir/all] Error 2
make: *** [all] Error 2

感谢您对解决问题的任何帮助。

【问题讨论】:

根据我在输出中看到的内容,我可以说问题出在 fortran“主”文件中。显然 fortran 代码不会生成“主”入口点。尝试编译一个没有任何外部 C++ 库的简单 fortran 代码,看看它是否有效 另外我会以make VERBOSE=1 的身份运行make(在CMake 生成的Makefile 上)以查看make(gcc、ld 等)发出的确切命令并能够重现自己解决问题,一步一步,根本没有任何“构建系统”,只有你自己,代码,编译器和链接器。 当我运行没有任何 cpp 文件的简单 fortran 代码时,它可以正常工作。我删除了与addition.cpp和addition.h相关的所有内容,以使其更简单(因此只剩下对func.cpp的调用);但是,我遇到了同样的错误。 不要单独使用fortran90标签。尤其是当您使用 Fortran 2003 C 互操作时。 【参考方案1】:

当您的主程序在 Fortran 中时,为什么要与 g++ 链接?换一种方式,链接gfortran并添加-lstdc++

只需添加一行:SET_TARGET_PROPERTIES(test.exe PROPERTIES LINKER_LANGUAGE Fortran)

或者使用更新的 GCC。即使使用您的原始设置,仍受支持的所有 GCC 版本都可以正常工作。

【讨论】:

以上是关于用于从 FORTRAN 代码调用的 C++ 函数调用 C++ 代码的 Cmake 配置文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Fortran 中的内存数据调用 C 代码

从 C++ 调用带有可选参数的 Fortran 子例程

从 C++ 调用带有可选参数的 Fortran 子例程

混合编程:从 C++ 调用 FORTRAN

如何运用c++里的“__stdcall”?

从 c++ 调用 FORTRAN 子例程会产生非法参数值