in
La comunitĂ  italiana dedicata a Sviluppatori e Architetti IT delle piattaforme Windows

fortran - c++

Ultimo messaggio ricevuto il 23-03-2004 17.09 da frea. 16 risposta(e).
Pagina 1 di 2 (18 elemento/i) 1 2 Successivo >
Ordina messaggi: Precedente Successivo
  • 23-03-2004 17.09

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    fortran - c++

    Salve a tutti,
    tempo fa avevo già provato a chiedere qualcosa di simile nel forum del c++, ma non avevo avuto risposte soddisfacenti. Dunque riprovo qui, che la domanda è a tema (spero).

    Devo richiamare subroutines scritte in fortran in un programma scritto in c++. Utilizzando cfortran.h sono riuscito a richiamare subroutines in fortran in un file scritto in c, ma non in c++ (basta infatti che rinomino il file .c in .cpp e non funziona più).

    Qualcuno sa come si fa?

    Grazie a tutti,
    Federico
    • No log
  • 23-03-2004 18.35 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    Ciao.

    Nella documentazione ufficiale dell'header CFORTRAN.H

    <a href="http://wwwasd.web.cern.ch/wwwasd/cernlib/cfortran.html">http://wwwasd.web.cern.ch/wwwasd/cernlib/cfortran.html</a>

    <a href="http://www-zeus.desy.de/~burow/cfortran/cfortran.html">http://www-zeus.desy.de/~burow/cfortran/cfortran.html</a>

    sono descritti per filo e per segno tutti i necessari accorgimenti (impossibile elencarli tutti in questa sede!) da adottare per utilizzare subroutines e dati globali (strutture, COMMON blocks...) FORTRAN in codice C/C++.

    Se ciò non fosse sufficiente, ti consiglio la lettura della pagina seguente

    <a href="http://www.neurophys.wisc.edu/comp/docs/notes/not017.html#fcall">http://www.neurophys.wisc.edu/comp/docs/notes/not017.html#fcall</a>

    che contiene alcuni illuminanti esempi sull'interoperabilità tra i due (tre) linguaggi, oltre ad ulteriori links sull'argomento.

    Infatti, C e C++ sono praticamente equivalenti nella capacità di usare codice FORTRAN, ma differiscono lievemente nella forma in cui ciò viene attuato (soprattutto per quanto riguarda la prototipizzazione delle subroutines: penso che i tuoi problemi stiano proprio qui - non disperarti, è un classico!).

    Inoltre, prova a dare un'occhiata alla documentazione eventualmente fornita con il tuo compilatore FORTRAN che, di solito, include quasi sempre una sezione dedicata all'interfacciamento di codice FORTRAN con codice C/C++ (mentre non si può dire altrettanto per i compilatori C/C++).

    Di più (e meglio!) non saprei dirti!

    Buon lavoro e fammi sapere (eventualmente, ne discutiamo in questa sede)!

    • No log
  • 28-03-2004 23.08 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Grazie mille,
    ora mi leggo tutto e ti faccio sapere...

    Federico
    • No log
  • 28-03-2004 23.28 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Ciao,
    in http://www.neurophys.wisc.edu/comp/docs/notes/not017.html#fcall ho preso il primo esempio, ma non mi funziona. L'esempio è il seguente:

    (1) The C++ file:

    // This illustrates how a Fortran routine and function may be
    // called from a main program in C++
    #include <iostream.h>
    extern "C"
    {
    void __stdcall FR1(int*,int *);
    int __stdcall FF1(int *);
    }
    void main()
    {
    int n=10,nSq,nCube;
    FR1(&n,&nSq);
    cout << "The square is:" << nSq << endl;
    nCube=FF1(&n);
    cout << "The Cube is:" << nCube << endl;
    }

    (2) The Fortran File:

    SUBROUTINE FR1(N,M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    M=N*N
    RETURN
    END
    C
    INTEGER FUNCTION FF1(N)
    C COMPUTES THE CUBE OF N
    FF1=N*N*N
    RETURN
    END

    Quando lo compilo mi da:
    file_cpp.cpp:9: syntax error before `(' token
    file_cpp.cpp:10: syntax error before `(' token
    file_cpp.cpp: In function `int main()':
    file_cpp.cpp:15: `FR1' undeclared (first use this function)
    file_cpp.cpp:15: (Each undeclared identifier is reported only once for each
    function it appears in.)
    file_cpp.cpp:17: `FF1' undeclared (first use this function)
    make: *** [file_cpp.o] Error 1

    da che potrebbe dipendere?

    Federico
    • No log
  • 29-03-2004 18.32 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    Ciao, frea.

    Per i primi due errori (riga #9 e #10) non so cosa dire, in quanto il codice è corretto e, provato da me con i compilatori gratuiti Borland C++ Compiler 5.5 e Open Watcom C++ 1.2 (che, tra l'altro, è un ottimo ambiente per lavorare in <i>mixed language</i>, in quanto supporta sia il C/C++ che il Fortran), produce regolarmente il relativo file .obj.

    Gli errori successivi potrebbero essere ingenerati da vari fattori: potresti fornirmi qualche informazione in più sulle operazioni da te svolte per produrre l'eseguibile finale (strumenti di sviluppo usati, righe di comando o makefiles utilizzati, eventuali variabili d'ambiente da te impostate)?

    Il successo o meno di tutta l'operazione è soggetto, purtroppo, a una quantità di specifiche condizioni!

    • No log
  • 30-03-2004 12.16 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Salve!
    ...dunque, il mio makefile è il seguente:

    CC = g++
    F = g77
    FLAGS = -c
    OBJ = file_cpp.o file_fortran.o

    g: $(OBJ)
    $(CC) $(OBJ) -o g

    clean:
    rm $(OBJ) g *~ \#* -f

    file_cpp.o: file_cpp.cpp
    $(CC) $(FLAGS) file_cpp.cpp
    file_fortran.o: file_fortran.f
    $(F) $(FLAGS) file_fortran.f

    Ho provato sia con g++ che con gcc; le versioni dei compilatori sono:
    g++ (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
    Copyright (C) 2002 Free Software Foundation, Inc.
    e
    gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
    Copyright (C) 2002 Free Software Foundation, Inc.

    Io penserei che i soli errori importanti siano quelli a riga 9 e 10, in quanto gli altri credo dipendano semplicemente da questi due. Secondo me non capisce "__stdcall" (che in realtà non capisco nemmeno io).

    Forse mi manca qualche libreria (oppure un riferimento a qualche libreria)?

    Frea
    • No log
  • 30-03-2004 13.46 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    No, credo non siano le librerie il tuo problema ma piuttosto la <b>symbol naming convention</b> usata dal tuo compilatore.

    Le <b>symbol naming conventions</b> (di cui <b>__stdcall</b> è un esempio) descrivono i metodi adottati dai compilatori nella mappatura dei simboli da noi usati nel sorgente (nel tuo caso i nomi dei due metodi <b>FR1</b> e <b>FF1</b>) nel file oggetto (*.obj) prodotto.

    Tale <b>symbol naming convention</b>, come ho detto, è dipendente dal compilatore e, più in generale, dalla piattaforma di sviluppo utilizzata.

    Ad esempio, nel caso della piattaforma da me impiegata per testare il codice da te fornito (<b>Open Watcom C/C++ e FORTRAN 77 versione 1.2</b>), durante il processo di compilazione dei sorgenti C++ e Fortran, il relativo compilatore C/C++ aggiunge un carattere <i>underscore</i> ai nomi dei metodi, mentre il compilatore Fortran converte i nomi dei simboli in maiuscolo.

    Per portare a termine con successo la compilazione e il linking dei due files oggetto nell'eseguibile finale mi è stato sufficiente aggiungere un carattere <i>underscore</i> ai nomi dei metodi nel file sorgente Fortran, in questa maniera:<code> SUBROUTINE FR1_(N,M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    M=N*N
    RETURN
    END
    C
    INTEGER FUNCTION FF1_(N)
    C COMPUTES THE CUBE OF N
    FF1=N*N*N
    RETURN
    END</code> e a togliere la parola che dichiara la convenzione di chiamata <b>__stdcall</b> dal codice C++, così:<code>extern "C"
    {
    void FR1(int*,int *);
    int FF1(int *);
    }</code>che produce lo sgradevole effetto di trasformare i nomi dei due metodi rispettivamente in <b>_FR1@8</b> e <b>_FF1@4</b> (sintassi non accettate in un sorgente Fortran). La soluzione da me adottata, invece, rende i simboli nei due files oggetto perfettamente compatibili, per cui il linker non ha più niente di cui lamentarsi e produce regolarmente il file eseguibile.

    Ti consiglio di osservare attentamente l'output del compilatore da te usato e vedere se ti fornisce qualche importante informazione al riguardo. Acquisiti gli eventuali ulteriori elementi, puoi quindi decidere come comportarti (d'altro canto, è la stessa cosa che ho messo in pratica io!).

    Fammi sapere.

    • No log
  • 30-03-2004 14.13 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    Scusa, nel digitare il post precedente, mi sono dimenticato di aggiungere il carattere <i>underscore</i> anche al nome della funzione presente, nel codice Fortran, alla riga<code>FF1=N*N*N</code> in maniera tale da trasformarla in<code>FF1_=N*N*N</code>
    • No log
  • 30-03-2004 19.42 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Grazie mille, mi sei stato di immenso aiuto.

    Ora ho capito come funziona il mio compilatore.
    Da me il programma corretto è il seguente:

    // This illustrates how a Fortran routine and function may be
    // called from a main program in C++

    #include <iostream>
    using namespace std;

    extern "C"
    {
    void fr1_(int*, int*);
    int ff1_(int*);
    }

    int main () {
    int n=10,nSq,nCube;
    fr1_(&n,&nSq);
    cout << "The square is:" << nSq << endl;
    nCube=ff1_(&n);
    cout << "The Cube is:" << nCube << endl;

    return 0;
    }

    SUBROUTINE FR1(N,M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    M=N*N
    RETURN
    END

    INTEGER FUNCTION FF1(N)
    C COMPUTES THE CUBE OF N
    FF1=N*N*N

    RETURN
    END

    Grazie ancora e a presto.
    Frea
    • No log
  • 30-03-2004 20.14 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Salve, sono ancora io.

    Ho fatto un minimo cambiamento e il programma non funziona più.
    Ho modificato il file fortran in:
    SUBROUTINE FR1(N,M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    real*8 M,N
    M=N*N
    print*,M
    RETURN
    END

    INTEGER FUNCTION FF1(N)
    C COMPUTES THE CUBE OF N
    real*8 M,N
    FF1=N*N*N

    RETURN
    END

    ossia ho inserito "print*,M" e non funziona più nulla.
    Mi dice:
    file_fortran.o(.text+0x1e): In function `fr1_':
    : undefined reference to `s_wsle'
    file_fortran.o(.text+0x35): In function `fr1_':
    : undefined reference to `do_lio'
    file_fortran.o(.text+0x3d): In function `fr1_':
    : undefined reference to `e_wsle'
    collect2: ld returned 1 exit status
    make: *** [g] Error 1

    cos'è, lo stesso errore di prima?
    Frea
    • No log
  • 31-03-2004 17.08 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    Allora...

    Intanto, per cominciare, ripeto per l'ennesima volta: quando postate per chiedere aiuto, cercate di non essere troppo parchi nel fornire dettagli sulle operazioni fatte per conto vostro e che hanno portato all'errore da voi segnalato! Vediamo di mettere a disposizione di chi, eventualmente, accorre in vostro aiuto il maggior numero possibile di elementi indiziari atti a guidarlo verso una corretta risposta!

    Per quanto riguarda il tuo problema, dagli elementi da te forniti (testualmente: "Ho modificato il file fortran... ") ho desunto che il codice da te utilizzato sia stato il seguente (adattato, ovviamente, secondo il mio ambiente di sviluppo, come illustrato nei miei precedenti posts):<code>-------------------------------------------------------------------
    * Sorgente FORTRAN:

    SUBROUTINE FR1_(N,M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    real*8 M,N
    M=N*N
    print*,M
    RETURN
    END
    C
    INTEGER FUNCTION FF1_(N)
    C COMPUTES THE CUBE OF N
    real*8 M,N ! il simbolo M non è mai referenziato
    FF1_=N*N*N
    RETURN
    END
    -------------------------------------------------------------------
    // Sorgente C++:

    #include <iostream.h>
    extern "C"
    {
    void FR1(int*,int *);
    int FF1(int*);
    }

    void main()
    {
    int n = 10, nSquare, nCube;

    FR1(&n, &nSquare);
    cout << "The square is: " << nSquare << endl;
    nCube = FF1(&n);
    cout << "The cube is: " << nCube << endl;
    }
    -------------------------------------------------------------------</code>Il programmino appena riportato compila senza alcun problema, pur non essendo esente da critiche. Nella fattispecie, nel sorgente FORTRAN la variabile di tipo <b>real M</b>, di dimensione pari a 8 bytes, <b>non viene mai referenziata</b> e, quindi, <b>è totalmente inutile</b>.

    Inoltre, il risultato ottenuto in output<code> 0.0000000000000000
    The square is: 0
    The cube is: 0</code> ci segnala la sussistenza di qualche problema nell'uso delle variabili che partecipano alle operazioni matematiche svolte dal codice FORTRAN.
    Infatti, la dichiarazione delle variabili <code>real*8 M,N</code>da te inserita in ambedue i metodi ivi contenuti (ed in questi ultimi mai inizializzate se non con il valore di default e cioè <b>zero</b>!) causa la prevalenza delle stesse variabili sugli argomenti dei metodi stessi, producendo in output il risultato sopra riportato.

    Sei sicuro che è questo ciò che volevi ottenere?

    • No log
  • 31-03-2004 19.44 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Salve,

    ....beh, non ho capito assolutamente niente. Quindi probabilmente devo essermi espresso piuttosto male; del resto non sono un informatico e quindi temo che molte delle mie espressioni siano senza significato. Ora proverò ad essere il più limpido possibile.

    Il programma è costituito da due file: file_cpp.cpp e file_fortran.f:

    file_cpp.cpp :

    #include <iostream>
    using namespace std;

    extern "C" {
    void fr1_(double*, double*);
    int ff1_(double*);
    }

    int main () {
    cout <<"Inserire numero, prego\n";
    double n;
    cin >>n;
    double nSq,nCube;
    fr1_(&n,&nSq);
    cout <<n<<"^2 = "<<nSq<<endl;
    nCube=ff1_(&n);
    cout <<n<<"^3 = "<<nCube<<endl;

    return 0;
    }

    file_fortran.f:

    SUBROUTINE FR1(N,M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    real*8 M,N
    M=N*N
    c print*,M
    RETURN
    END

    INTEGER FUNCTION FF1(N)
    C COMPUTES THE CUBE OF N
    real*8 N
    FF1=N*N*N

    RETURN
    END

    Così com'è a me compila perfettamente e da il risultato voluto. Se però scommento la riga print*,M del file file_fortran.f allora non compila più e mi dice:

    g77 -c file_fortran.f
    g++ file_cpp.o file_fortran.o -o g
    file_fortran.o(.text+0x1e): In function `fr1_':
    : undefined reference to `s_wsle'
    file_fortran.o(.text+0x35): In function `fr1_':
    : undefined reference to `do_lio'
    file_fortran.o(.text+0x3d): In function `fr1_':
    : undefined reference to `e_wsle'
    collect2: ld returned 1 exit status
    make: *** [g] Error 1

    Il makefile utilizzato e le versioni dei compilatori sono quelle dell'altra volta.

    Grazie mille e a presto,
    Frea
    • No log
  • 01-04-2004 1.11 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    Bene, ti sei deciso a postare il codice completo e, come al solito in questi casi, è tutta un'altra storia!

    Ragioniamoci sopra...

    E' vero, il prodotto della compilazione del tuo codice è un programma funzionante, sebbene c'è un punto che mi lascia piuttosto perplesso. Nella funzione <b>FF1</b> esegui il calcolo del cubo in doppia precisione <b>ma il valore restituito è di tipo intero (!)</b>. Ma , allora, che senso ha svolgere l'operazione in doppia precisione, non ti pare? :-|

    Personalmente, il codice completo definitivo di questo pur semplice programmino lo vedrei così:<code>---------------------------------------------
    // File header CPPFOR77.H:

    #include <iostream.h>
    #include <conio.h>

    extern "C"
    {
    void FR1(double*, double *);
    double FF1(double*);
    }
    ---------------------------------------------
    * File sorgente FOR77.FOR:

    SUBROUTINE FR1_(N, M)
    C COMPUTES THE SQUARE OF N, RETURNS IN M
    REAL*8 M, N
    M = N**2
    RETURN
    END
    C
    REAL*8 FUNCTION FF1_(N)
    C COMPUTES THE CUBE OF N
    REAL*8 N
    FF1_ = N**3
    RETURN
    END
    ---------------------------------------------
    // File sorgente CPP.CPP:

    #include "cppfor77.h"

    int main()
    {
    double n, nSquare, nCube;

    cout << "Inserire il valore della variabile reale ""n:"" ";
    cin >> n;
    cout << endl;

    FR1(&n, &nSquare);

    cout << n << "^2 = " << nSquare << endl;

    nCube = FF1(&n);

    cout << n << "^3 = " << nCube << endl;
    cout << "\nPremere un tasto per terminare... ";

    getch();

    cout << endl;

    return 0;
    }
    ---------------------------------------------</code>Per quanto riguarda il problema da te riscontrato con l'istruzione <b>PRINT*, M</b>, non saprei, onestamente, cosa pensare: in primo luogo, perchè a me non succede 8-) e, in secondo luogo, perchè non riesco a capire a cosa si riferiscono i simboli <b>s_wsle</b>, <b>do_lio</b> ed <b>e_wsle</b> (nel mio file oggetto tali simboli non esistono!). Poichè probabilmente sono simboli generati internamente da codice di libreria, l'unica cosa che ti consiglio di fare è quella di dare un'occhiata, con un editor esadecimale, al contenuto delle rispettive locazioni indicate all'interno del file oggetto file_fortran.o(<b>.text+0x1e</b>), file_fortran.o(<b>.text+0x35</b>) e file_fortran.o(<b>.text+0x3d</b>) (ciascuna delle quali si riferisce al relative virtual address della sezione codice - .text - più l'offset indicato) e vedere, per curiosità, cosa trovi la' in giro.

    Inoltre, potresti provare a togliere l'asterisco che segue il token PRINT in quanto, di norma, il FORTRAN standard non lo prevede e osservare se cambia qualcosa.

    Buona fortuna! ;-)

    • No log
  • 01-04-2004 14.33 In risposta a

    • frea
    • Utente Top 25
    • Registrato il 07-11-2003
    • Messaggi 30

    Re: fortran - c++

    Ciao!

    Innanzitutto una stranezza. Se metto real*8 alla funzione FF1(N), come ovviamente sarebbe logico, mi da come risultato sempre 0.
    Poi... io non so nemmeno cosa sia un editor esadecimale!
    ...e mi sembra che per questa strada le cose si complichino a dismisura. Dunque pensavo questo: a te funziona tutto, giusto? Dunque utilizzerai un compilatore molto meglio del mio... beh, dimmi qual è che lo utilizzo anch'io e mi funzionerà tutto anche a me!
    Oppure, seconda possibilità: utilizzo cfortran.h anche per il c++, del resto per il c funziona benone..... l'unico problema è, come dicevo all'inizio, che non so come si fa. Te lo hai mai usato?

    Frea
    • No log
  • 01-04-2004 15.02 In risposta a

    • Deep_Core
    • Utente Top 10
    • Registrato il 05-01-2004
    • Italy - Trieste
    • Messaggi 319

    Re: fortran - c++


    Ciao, frea.

    Come ti ho già detto, se vuoi proprio programmare in mixed C++/Fortran e non sei molto pratico di tutti i dettagli, ti consiglio di scaricarti l'ambiente gratuito :-P <b>Open Watcom C/C++ and Fortran</b>, che trovi all'indirizzo <a href="http://www.openwatcom.org/">http://www.openwatcom.org/</a> e installarlo sulla tua macchina. La procedura è guidata e non presenta problemi di sorta: comunque, durante tale fase, <b>leggi attentamente le informazioni mostrate a video</b>, mi raccomando!

    Riguardo alla tua ultima domanda, personalmente uso alcuni header files (scritti da me) che mi risolvono tutti i problemi di compatibilità tra le varie <i>symbol naming conventions</i> in cui posso incappare durante la mia abituale pratica di programmazione (nel valutare quanto ti ho appena detto, tieni presente che io sono un programmatore di professione! 8-) ).

    A questo punto, però, permettimi, una domanda: vista la tua scarsa (o nulla) preparazione per quanto riguarda la programmazione in generale, perchè insisti tanto con il <i>mixed language programming</i>?

    Ti obbligano con la forza o te l'ha ordinato il dottore? :-D

    • No log
Pagina 1 di 2 (18 elemento/i) 1 2 Successivo >
Prelevato da http://www.devspy.com/forums/t/857.aspx
DevSpy.com 6.0 © 2001-2008 - Alcuni Diritti Riservati
Salvo diversa indicazione, tutti i contenuti sono pubblicati sotto licenza "Creative Commons Attribution-Share Alike 3.0"