Fortran与C++混合编程:Fortran不能调用C++子程序

4

最近,我参与了一个项目,在该项目中,一些C ++子程序由Fortran脚本调用(一个Fortran求解器打算具有来自在C ++中开发的库的一些数据后处理能力)。以下流程重现了产生错误的过程。这里我使用相当简单的Fortran和C ++脚本进行简单明了的演示。

一个简单的Fortran主程序调用CXX子程序: CXX子程序-sub1.cxx:

    #include <stdio.h>
    using namespace :: std;
    extern "C" void func_c_();
    void func_c_()
    {
         printf("%d\n", 100);
    }

Fortran主程序-sub2.f90:
    program func_fortran
          implicit none
          call func_c()
    end program func_fortran

编译它们:
    g++ -c sub1.cxx
    gfortran -o test sub2.f90 sub1.o

我们得到了可执行文件 - test。到目前为止,没有任何问题。
然后我们用sub1.1.cxx替换了sub1.cxx文件。代码如下:
    #include <iostream>
    using namespace :: std; 
    extern "C" void func_c_();
    void func_c_()
    {
         cout << "I am a CXX." << endl;
    }

Fortran 的主程序与之前完全相同,我们没有改动它。

现在我们编译代码:

    g++ -c sub1.1.cxx
    gfortran -o test sub2.f90 sub1.1.o

我们可以获取sub1.1.o文件。但是会出现错误消息:
    sub1.1.o: In function `func_c_':
    sub1.1.cxx:(.text+0xa): undefined reference to `std::cout'
    sub1.1.cxx:(.text+0xf): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
    sub1.1.cxx:(.text+0x14): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
    sub1.1.cxx:(.text+0x1c): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
    sub1.1.o: In function `__static_initialization_and_destruction_0(int, int)':
    sub1.1.cxx:(.text+0x46): undefined reference to `std::ios_base::Init::Init()'
    sub1.1.cxx:(.text+0x55): undefined reference to `std::ios_base::Init::~Init()'
    collect2: error: ld returned 1 exit status

与sub1.cxx相比,sub1.1.cxx似乎无法识别一些C++标准,例如std::cout。有人可以解决这个问题吗? 此外,我在这里没有使用Fortran 2013中的iso_c_binding功能。我在其他情况下尝试过这个功能,但也没有起作用。

2
FORTRAN 链接器不知道如何链接 C++ 运行时库,这就是为什么您会看到这些错误。您的第一个 C++ 片段本质上只是 C 代码,这可能解释了为什么它能够成功链接。 - Mansoor
2
请注意 - Fortran 官方拼写方式已经三十年来一直是小写的 Fortran。 - Ian Bush
嗨,Mansoor,嗨,Lan Bush,感谢您的评论。请看一下Francesco发布的内容。那是正确的解决方案。为了使C和C++之间兼容编译,应使用链接标志-lstdc++。 - Hacunamatata
1个回答

7
您需要将可执行文件与C++标准库链接起来:
g++ -c sub1.1.cxx
gfortran -o test sub2.f90 sub1.1.o -lstdc++

使用gfortran/g++,您还可以使用 g++来链接Fortran库:

g++ -c sub1.1.cxx
gfortran -c sub2.f90
g++ -o test sub1.o  sub2.o -lgfortran

1
嗨@Hacunamatata,如果此回答或任何解决方案已经解决了您的问题,请考虑通过点击勾选标志接受它。这将向更广泛的社区表明您已找到解决方案,并为回答者和您自己赢得一些声誉。没有义务这样做。 - francesco
嗨,Fransesco。非常感谢您的评论。现在它可以工作了。我曾经在gfortran之后添加标志- -lstdc++,而不是将其附加到最后。显然,这不是定义链接行为的正确方式。再次感谢您的友善评论。 - Hacunamatata
@Hacunamatata 是的,顺序很重要,参见,例如,这里 - francesco
你在这里提供的链接非常有帮助。谢谢。 - Hacunamatata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接