2013-10-09 12 views
5

Ho eseguito alcune ricerche online ma non riesco a capire come compilare un semplice codice C++ e Fortran da Linux. Ho bisogno di diventare complesso con esso, ma ho solo bisogno di sapere come iniziare con un semplice esempio.Edizione mista di collegamento C++ e Fortran

codice

mio C++ è questo:

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

mio Fortran Codice è questo:

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 

Sto usando ifort per compilare il mio codice Fortran e g ++ per il codice C++. Ho provato questo comando da terminale:

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

Ma l'errore che sto ottenendo dice "file di input del linker inutilizzato perché collegamento non fatta". Non sono sicuro di come collegare i due insieme. Se qualcuno potesse aiutarmi, lo apprezzerei molto!

PS - Ho provato ad aggiungere -lg2c alla fine della mia linea di compilazione e non è riconosciuto.

+2

si 'g ++' sembra sbagliato, dovrebbe essere 'g ++ -o Program.o Main.cpp –

+0

@ZacWrangler Non dovrebbe, perché il programma C++. Sovrascriverebbe Fortran Program.o precedentemente costruito. Piuttosto, avere nomi di file oggetto diversi. – milancurcic

risposta

8

Qui ci sono alcuni problemi che non consentono la corrispondenza dei nomi degli oggetti. In primo luogo, specificare nel codice C++ che le funzioni esterni hanno la firma C:

In test.cpp:

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

Vedere In C++ source, what is the effect of extern "C"? per maggiori dettagli.

Nel codice Fortran, rendere l'interfaccia esplicita posizionando le procedure nel modulo e utilizzare iso_c_binding per consentire agli oggetti Fortran di apparire come oggetti C validi. Si noti che siamo in grado di specificare in modo esplicito i nomi degli oggetti che il C o C++ programmi vedranno attraverso la parola 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 

compilazione (non mente me utilizzando la suite di Intel , il mio g ++ & gfortran sono molto vecchi):

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

link:

$ icpc test_f.o test.o 

L'esecuzione di a.out dovrebbe ora funzionare come previsto.

+0

Grazie mille ha lavorato come un campione! – user2863626

+1

Nota l'istruzione 'use iso_c_binding' è superflua per il codice presentato - nessuna entità da quel modulo è in fase di accesso. – IanH

+0

@IanH Ah non me ne sono reso conto. Ho modificato il codice per rimuovere la ridondanza :). – milancurcic