2013-10-09 20 views
5

Ich habe einige Online-Suche gemacht, aber ich kann nicht herausfinden, wie man einen einfachen C++ - und Fortran-Code von Linux kompilieren. Ich muss komplex werden, aber ich muss nur wissen, wie man mit einem einfachen Beispiel beginnt.Mixed C++ und Fortran Linking Problem

Meine C++ Code ist dies:

#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; 
} 

Mein Fortran-Code, ist dies:

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 

ich ifort bin mit meinem Fortran-Code und g ++ für C++ Code zu kompilieren. Ich habe diesen Terminal-Befehl versucht: „Linker Eingabedatei ungenutzt, da keine Bindung getan“

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

Aber die Fehler, die ich bekommen habe, sagen Ich bin nicht sicher, wie man die zwei zusammen verbindet. Wenn mir jemand helfen könnte würde ich es sehr schätzen!

PS - Ich habe versucht, -lg2c am Ende meiner Kompilierungslinie hinzuzufügen, und es wird nicht erkannt.

+2

Sie scheint 'g ++' falsch, sollte 'g ++ -o Program.o Main.cpp –

+0

@ZacWrangler Es sollte nicht, weil die C++ Program.o überschreiben zuvor erstellten Fortran Program.o. Stattdessen haben Sie unterschiedliche Objektdateinamen. – milancurcic

Antwort

8

Hier gibt es einige Probleme, bei denen die Namen der Objekte nicht übereinstimmen. Zuerst geben Sie im C++ Code, der die externen Funktionen der C-Signatur:

In test.cpp:

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

Siehe In C++ source, what is the effect of extern "C"? für weitere Details.

In Ihrem Fortran-Code machen Sie die Schnittstelle explizit, indem Sie Prozeduren in das Modul einfügen, und verwenden Sie iso_c_binding, damit Fortran-Objekte als gültige C-Objekte angezeigt werden. Beachten Sie, dass wir explizit die Namen der Objekte, die die C- oder C++ Programme sehen durch das bind Stichwort angeben:

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 

Compile (mich nicht dagegen die Intel-Suite , meine g ++ & gfortran sind sehr alt):

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

-Link:

$ icpc test_f.o test.o 

Die Ausführung von a.out sollte jetzt wie erwartet funktionieren.

+0

Vielen Dank, arbeitete wie ein Champion! – user2863626

+1

Beachten Sie, dass die Anweisung 'iso_c_binding verwenden' für den angegebenen Code überflüssig ist - auf Entitäten aus diesem Modul wird nicht zugegriffen. – IanH

+0

@IanH Ah, das habe ich nicht bemerkt. Ich habe den Code bearbeitet, um Redundanz zu entfernen :). – milancurcic