C++ nach Fortran



  • Ich weiss nicht genau, ob es funktioniert, aber versuch mal die Funktion so zu deklarieren

    extern "C" void fortran_func(char *string);
    

    Du musst eben Sicherstellen, dass die größe des char in Fortran und C++ gleich sind.



  • Hallo, danke erst einmal fuer Eure Antworten, habe das im Internet gefunden,
    weiss jetzt aber immer noch nicht, wie ich den String an diese ominoese .obj Datei uebergebe!!!
    Bin immer noch ratlos!!!

    Fortran und C aus C++ Im Gegensatz zu FORTRAN und C verwendet C++ grundsätzlich ein typsicheres Binden verschiedener Module zu einem ausfürbaren Programm. Dazu kodiert C++ die Typinformationen der Parameter einer Funktion in einen internen Funktionsnamen (Namemangeling). Dieser C++-Funktionsname wird dann in Object- und Bibliotheksdateien abgelegt. Da FORTRAN und C kein Namemangeling verwenden, lassen sich Unterprogramme dieser Sprachen nicht unmittelbar aus C++ heraus aufrufen. Durch Angabe der Deklaration

    extern "C" function (TYPE1 param1,...);

    oder besser noch in einem Headerfile
    zu einer C-Modul, das von C++ benutzt wird:

    /* --- Dateianfang --- */
    #if defined (__cplusplus)
    extern "C"
    {#endif
    
    /* Typdefinitionen, Funktionsdeklarationen, ...*/
    #if defined (__cplusplus)
    }
    #endif/
    * --- Dateiende --- */
    

    kann das Namemangeling (und damit auch das typsichere Binden) von C++ unterdrückt werden. C-(Bibliotheks-) Funktionen lassen sich damit problemlos aus C++ verwenden; FORTRAN-Funktionen in der gleichen Weise wie dies aus C-Programmen heraus möglich ist



  • Helfen kann ich nur bedingt. Hier noch ein paar Ideen:

    Du schreibst du hast eine .obj-Datei, die mit Fortran erstellt wurde.
    Gibt's auch den Quellcode noch?
    Wie sieht die Deklaration der Funktion in Fortran aus?
    Erwartet sie einen gewöhnlichen Fortran-string?
    Wenn ja, musst du wie gesagt erst den C-string in Fortran-Format konvertieren.
    (siehe dazu Anleitung des Fortran-Compilers)

    Schliesslich musst Du herausbekommen was für eine Aufrufkonvention der Fortran-Compiler verwendet.
    (Aufrufkonvention = Festlegung der Art und Weise wie Parameter auf dem Stack übergeben werden, und wer sich um das aufräumen des Stacks kümmert)
    Mit ein bisschen Glück handelt es sich um die C-Aufrufkonvention und du kannst mit dem oben beschriebenen extern "C" arbeiten.
    (die letzten Sätze aus deinem Text deuten dies an)
    Ansonsten im C++-Compiler die spezielle Aufrufkonvention für die Fortran-Funktion explizit angeben.



  • Also ich habe folgendes probiert, erhalte aber einen Segfault (g77 und g++ 3.0.4)
    (Compiliert wie folgt
    g77 -c -o cpptof.o cpptof.f
    g++ cpptof.o -o cpptof cpptof.cc 😵
    Fortran Code:

    c C++ String to Fortran Demo
    c
          integer function ffunc(a,n)
          character a(*)
          integer n
    c     a is a string with the size of n
          integer i
    c
          do 10 i = 1 , n
             a(i) = ' '
     10   continue
    c
          return
          end
    

    C++ Code:

    #include <iostream>
    
    extern "C" int ffunc_(char *a,size_t n);
    
    int main(void)
    {
      char demo[12]="hello world";
    
      std::cout << demo << std::endl;
      ffunc_(demo,5);
      std::cout << demo << std::endl;
    }
    

    Der G77 benutzt irgend wie als Postfix für Funktionsnamen ein _, schau am besten mal, ob dein Compiler auch so etwas macht (entweder in der Bedienungsanleitung oder mit dem nützlichen Tool nm (aus den GNU/binutils)).



  • @kingruedi

    ich hab mal Dein Fortran-Programm mit CVF vers. 6.6 kompiliert. Jetzt die Frage: welche Datei und vor allem wie binde ich diese an das kompilierte C- (bzw. C++ Programm)Programm?



  • mit den Compaq Compilern kenn ich mich nicht aus, aber du musst folgendes tun

    Fortran Code zur Objekt Datei compilieren
    C(++) Code zur Objekt Datei compilieren

    Beide Objekt Dateien linken



  • Ich habe versucht in der MFC die obj-Datei von Fortran zu linken, bekomme jedoch die Fehlermeldung:
    Linking...
    LINK : fatal error LNK1104: cannot open file "F_2.obj"
    Error executing link.exe.
    Source-Code ist der oben beschriebene, habe diesen in Fortran CVF 6.0 compiliert.
    Was kann ich machen, dass er die obj-Datei oeffnet?



  • OK habe den Pfad falsch gesetzt, jetzt bekomm ich aber flgende Fehlermeldug beim Versuch die Fortran obj zu linken.

    Linking...
    C_3.OBJ : error LNK2001: unresolved external symbol _ffunc_
    Debug/C_3.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.

    das bezieht sich auf die in C++ deklariertr Fuktion:
    extern "C" int ffunc_(char *a,size_t n); ?
    Warum kommt erdamit nicht klar?



  • das bezieht sich auf die in C++ deklariertr Fuktion:
    extern "C" int ffunc_(char *a,size_t n); ?
    Warum kommt erdamit nicht klar?

    Fortran uebergibt alle Parameter als Zeiger an die Funktion. Entsprechend bekommt er auch ein size_t* n. Ausserdem werden mehrdimensionale Arrays in anderer Reihenfolge als in C gespeichert.

    ausfuehrlicheres findet man bei den Compilerbeschreibungen, z.B. PGI
    [url] http://www.pgroup.com/ppro_docs/pgiws_ug/pgiug_07.htm#Heading96 [/url]

    Tschuess, Seppel.



  • @Seppel
    ahhh, ich hab noch dran gedacht, dass FORTRAN ja immer Call-by-Reference macht und C immer Call-by-Value. Ich Trottel war nur zu doof das umzusetzen.

    Jetzt geht es natürlich prima 🙂

    BTW.
    hat jemand Ahnung, wie man Strukturen übergibt? BZW. Wie man die in Fortran ausliest, da bis Fortran 90 Strukturen ja unbekannt sind.

    Muss man wahrscheinlich vom Compiler abhängig machen, die Werte auslesen und die Padding Bytes ignorieren. Schau ich mir mal an, wie das gehen könnte..


Anmelden zum Antworten