努力将 f90 子例程与 C 程序链接

问题描述 投票:0回答:1

简单的程序

主.C

#include <iostream>
void sub3();

int main(void)
{
    std::cout << "Hello from C World\n";
        sub2();
    sub3();
    return(0);
}
void sub2(){
    std::cout << "Sub1\n";
    return;
}

和 sub3.f90

    subroutine sub3() 
    write(*,*) 'Hello from F90 sub3'
    return
    end

使用Ubuntu,

gfortran -c -fno-下划线 sub3.f90

应该防止名称被附加下划线破坏

gcc(或 g++)main.C -c

使用 -lgfortran -lsdtc++ 组合与 gfortran 或 gcc 链接

找不到将 sub3 或 sub3() 作为定义参考的组合。

最好是 CMake 也能工作

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(ProjName VERSION 0.1.0 LANGUAGES  C CXX Fortran)
include(FortranCInterface)

set( CMAKE_CXX_FLAGS "-lgfortran")
set( CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -lstdc++ -fno-underscoring")
set( CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}  )
add_library(ProjFLib sub3.f90 )
add_executable( ProjTest  main.C  )
target_link_libraries( ProjTest  ProjFLib )

无论附加(或抑制)下划线,都无法获得链接组合,某些迭代具有对 throw_*length_*errror 、运算符 delete() 的未定义引用,...

gcc cmake fortran gfortran
1个回答
0
投票

一些小修复和改进以使其正常工作:

  • 您需要通过将原型放入
    extern "C"
    块中来禁用 C++ 名称修改。
  • 为了避免依赖非标准 Fortran 编译器选项来禁用 Fortran 名称修改,请使用
    bind(C)
    功能。
  • 我必须将
    sub2()
    放在
    main()
    之前,否则编译器会抱怨缺少声明。 (或者编写原型也可以。)

因此,main.cpp:

#include <iostream>
extern "C" {
    void sub3();
}

void sub2(){
    std::cout << "Sub1\n";
    return;
}
int main(void)
{
    std::cout << "Hello from C World\n";
    sub2();
    sub3();
    return(0);
}

sub3.f90:

subroutine sub3() bind(C, name="sub3") 
    write(*,*) 'Hello from F90 sub3'
    return
end

编译并运行:

$ gfortran -O2 -Wall -c sub3.f90
$ g++ -O2 -Wall main.cpp sub3.o -lgfortran
$ ./a.out 
Hello from C World
Sub1
 Hello from F90 sub3
© www.soinside.com 2019 - 2024. All rights reserved.