2012-04-24 14 views
6

Ich möchte in meiner Fortran-Anwendung Netzwerkfunktionen aufrufen können. Mein Chef möchte, dass ich in Fortran alles mache, anstatt C und Fortran zu benutzen. Wir haben bereits eine Version der Anwendung mit PGI Fortran Compiler unter Windows gemacht. Wir verschieben es auf Linux, wo wir wahrscheinlich ihren Compiler verwenden werden. Im Moment benutze ich gfortran.Sockets Programmierung gfortran

Ich habe eine Schnittstelle für diese Netzwerkanrufe erstellt, und alles kompiliert und verknüpft. Der Code unten ist etwas, was ich ähnlich mache, außer dass die Schnittstellen und Konstanten in einem Modul sind.

PROGRAM MAIN 

    INTEGER,PARAMETER ::AF_INET = 2 
    INTEGER,PARAMETER ::SOCK_STREAM = 1 
    INTEGER,PARAMETER ::IPPROTO_TCP = 6 

    INTERFACE 
     FUNCTION socket(domain,type,protocol) 
     INTEGER ::socket,domain,type,protocol 
     END FUNCTION 
    END INTERFACE 

    sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) 
    WRTIE(*,*)"Socket returned: ",sock 

END PROGRAM 

Wenn ich das Programm ausführen, scheitert die Socket-Funktion -1 zurückgeben. Ich weiß nicht wirklich was los ist. Ich füge keine Bibliotheken in der Befehlszeile hinzu, also nehme ich an, dass es korrekt mit den Standardbibliotheken verknüpft ist. Ich kompiliere mit

gfortran -o MAIN_PROGRAM MAIN_PROGRAM.f90 -fno-underscoring 
+0

Haben Sie versucht, errno zu überprüfen? –

Antwort

8

Sie können das in Fortran 2003 eingeführte ISO_C_Binding verwenden, um auf C-Bibliotheksfunktionen zuzugreifen. Dies ist die sauberste und portabelste Option, die Sie haben. Die Gfortran documentation enthält einige Details, wie jedes andere Herstellerhandbuch. Es gibt auch einige Projekte, die darauf abzielen, Schnittstellen zu POSIX für Fortran 90 zu implementieren: fortranposix und posix90. Aber wie gesagt, eine korrekte C-Binding-Schnittstelle unter Verwendung der F2003-Fähigkeiten ist wahrscheinlich die sauberste Option, siehe auch die fortranwiki.

Edit: Hier wird der Code mit dem ISO-C-Bindung Leim hinzugefügt (getestet mit gfortran 4.4.5):

program testsocket 
    use, intrinsic :: iso_c_binding 

    implicit none 

    interface 
    function socket(domain, type, protocol) bind(c, name="socket") 
     use, intrinsic :: iso_c_binding 
     integer(kind=c_int) :: socket 
     integer(kind=c_int), value :: domain, type, protocol 
    end function socket 
    end interface 

    integer :: sock 

    sock = socket(2_c_int, 1_c_int, 6_c_int) 

    write(*,*) "Socket returned: ", sock 

end program testsocket 
+1

Ah! Ich sehe mein Problem. Ich übergebe die Argumente mit Aufruf von Verweis so Socket() wird nicht mit gültigen Optionen aufgerufen. Vielen Dank! – hw12

0

Hier ist eine Vermutung. Du bist ein Doktorand in Naturwissenschaften oder Technik (aber nicht Informatik oder Computertechnik) und dein Chef wurde vor 1950 geboren. Wenn ja, ich habe in deinen Schuhen gestanden (außer dass in meinem Fall die Anforderung war, Fortran 77 zu verwenden) . Ich fühle deinen Schmerz.

Wie Sie wahrscheinlich wissen, verwendet Fortran keine Header-Dateien für Prototyp-Funktionsaufrufe auf die gleiche Weise wie C. Sie können eine Fortran-Funktion ohne den Header aufrufen, wenn die Typen der Argumente nicht überprüft werden.

Allerdings gibt es dieses Problem - oder früher gab es dieses Problem, denn meine jüngste Erfahrung ist mehrere Jahre veraltet. Im Vergleich zu C fügt GNU Fortran dem Namen jeder Funktion einen versteckten Unterstrich hinzu. Es fällt auch der Name der Funktion.

Das Programm readelf -a kann Ihnen hier helfen. Verwenden Sie es für die Objektdatei, die Ihr Fortran-Compiler ausgibt. Suchen Sie in der Ausgabe nach dem Symbol socket. Wenn meine Erinnerung stimmt, sehen Sie dort eine .

Wenn Sie wirklich, wirklich überhaupt kein C verwenden können - sogar eine Wrapper-Funktion mit dem C-Namen _socket() - dann gebe ich zu, dass ich nicht weiß, was Sie als nächstes tun sollten. In diesem Fall könnten Sie an einer engen Stelle stecken bleiben. So oder so, viel Glück.

Update: Ich empfehle @ M.S.B.'s Kommentar unten.

+6

Sie können die Benennung von Funktionen mit der von Haraldki beschriebenen ISO C-Bindung kontrollieren und die Unterstriche vermeiden. Fortran und C zu mischen ist viel einfacher und portabler als früher. –

+3

Ich wurde 1982 geboren und ich bin Fortran für neue Projekte. Ich habe sogar eine Menge Code von C übersetzt. Ich habe etwas Schlechtes mit mir? –

+0

@VladimirF: Nein, nichts schlimmes natürlich.Fortran ist ein Werkzeug, um eine Arbeit zu erledigen, und Sie verwenden es, um die Arbeit zu erledigen. Schön für dich. Wenn Sie wissen wollen, war meine Erfahrung umgekehrt. Ich musste Fortran 77 (nicht einmal den modernen Fortran) für Zwecke verwenden, für die C oder sogar Perl besser geeignet waren. Es machte mir nichts aus. Ich wurde bezahlt, und ich stritt nie mit meinem Chef darüber; aber wenn Sie mich fragen, ob ich denke, dass mein Chef in diesem Fall die richtige Wahl getroffen hat, würde ich sagen, dass ich das nicht glaube. Was dich betrifft: geh Fortran! – thb