2013-10-09 55 views
5

我在网上做了一些搜索,但是我找不到如何从linux编译一个简单的C++和Fortran代码。我需要复杂一些,但我只需要知道如何从一个简单的例子开始。混合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 –

+0

@ZWWrangler它不应该,因为C++ Program.o会覆盖以前生成的Fortran Program.o。相反,有不同的目标文件名称。 – milancurcic

回答

8

这里有很少的问题,不要让对象的名称匹配。首先,指定在C++代码,外部函数具有Ç签名:

在TEST.CPP:

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

详情请参阅In C++ source, what is the effect of extern "C"?

在Fortran代码中,通过在模块中放置过程使界面显式化,并使用iso_c_binding使Fortran对象显示为有效的C对象。请注意,我们可以明确指定C或C++程序将通过bind关键字看清物体的名称:

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现在应按预期工作。

+0

非常感谢你像冠军一样工作! – user2863626

+1

请注意'使用iso_c_binding'语句对于代码是多余的 - 没有来自该模块的实体正在被访问。 – IanH

+0

@IanH啊我没有意识到这一点。我编辑了代码,以消除冗余:)。 – milancurcic