混合使用 C++ 和 Fortran 的链接问题

7
我是一名有用的助手,可以为您翻译文本。

我在网上进行了一些搜索,但无法找到如何从Linux编译简单的C++和Fortran代码。我需要深入了解它,但我只需要知道如何从简单的示例开始。

我的C ++代码如下:

#include <iostream>
using namespace std;

extern int Add( int *, int * );
extern int Multiply( int *, int * );

int main()
{
    int a,b,c;  
    cout << "Enter 2 values: ";
    cin >> a >> b;

    c = Add(&a,&b);
    cout << a << " + " << b << " = " << c << endl;
    c = Multiply(&a,&b);
    cout << a << " * " << b << " = " << c << endl;
    return 0;
}

我的Fortran代码如下:

integer function Add(a,b)
    integer a,b
    Add = a+b
    return
end


integer function Multiply(a,b)
    integer a,b
    Multiply = a*b
    return
end

我正在使用ifort编译Fortran代码,使用g++编译C++代码。我尝试了这个终端命令:

$ ifort -c Program.f90
$ g++ -o Main.cpp Program.o

但是我得到的错误信息说“链接器输入文件未使用,因为没有进行链接。”我不确定如何将它们连接在一起。如果有人能帮我解决这个问题,我将非常感激!
PS-我已经尝试在编译行末尾添加-lg2c,但它无法识别。

2
你的 g++ 命令好像有误,应该是 g++ -o Program.o Main.cpp - Zac Wrangler
@ZacWrangler 不应该这样,因为 C++ Program.o 会覆盖之前构建的 Fortran Program.o。相反,应该使用不同的目标文件名。 - milancurcic
1个回答

9

这里有几个问题导致对象名称不匹配。首先,在C++代码中指定外部函数具有C签名:

在test.cpp中:

extern "C" int Add( int *, int * );
extern "C" int Multiply( int *, int * );

请查看在C++源代码中,extern "C"有什么效果?以获取更多详细信息。
在您的Fortran代码中,通过将过程放入模块中并使用iso_c_binding让Fortran对象显示为有效的C对象来明确接口。请注意,我们可以通过bind关键字显式指定C或C++程序将看到的对象的名称:
test_f.f90:
module mymod
use iso_c_binding
implicit none

contains

integer(kind=c_int) function Add(a,b) bind(c,name='Add')
    integer(kind=c_int) :: a,b
    Add = a+b
end function

integer(kind=c_int) function Multiply(a,b) bind(c,name='Multiply')
    integer(kind=c_int) :: a,b
    Multiply = a*b
end function

endmodule mymod

编译(请不要介意我使用英特尔套件,因为我的g++和gfortran非常老):

$ ifort -c test_f.f90 
$ icpc -c test.cpp 

链接:

$ icpc test_f.o test.o

执行a.out现在应该如预期的那样工作。


1
请注意,对于所呈现的代码,use iso_c_binding语句是多余的 - 没有访问该模块中的任何实体。 - IanH
@IanH 啊,我没意识到。我编辑了代码以消除冗余 :)。 - milancurcic
这比处理那些疯狂的无下划线编译器标志要好得多! - knedlsepp

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