2012-04-24 19 views
6

Desidero poter chiamare le funzioni di rete nella mia applicazione Fortran. Il mio capo vuole che faccia tutto in Fortran invece di usare C e Fortran. Abbiamo già realizzato una versione dell'applicazione utilizzando il compilatore Fortran di PGI su Windows. Lo stiamo spostando su Linux dove probabilmente useremo il loro compilatore. In questo momento sto usando gfortran.programmazione socket gfortran

Ho creato un'interfaccia per queste chiamate di rete, e tutto compila e collega. Il codice seguente è qualcosa di simile a quello che sto facendo eccetto che le interfacce e le costanti sono in un modulo.

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 

Quando si esegue il programma, la funzione socket non riesce a restituire -1. Non so davvero cosa sta succedendo. Non aggiungo alcuna libreria sulla riga di comando quindi suppongo che stia collegando correttamente le librerie predefinite. Compilare utilizzando

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

Hai provato di controllare errno? –

risposta

8

È possibile utilizzare ISO_C_Binding introdotto in Fortran 2003 per accedere alla funzionalità della libreria C, questa è l'opzione più pulita e più portatile che si abbia. Lo Gfortran documentation ha alcuni dettagli su di esso, come qualsiasi altro manuale del fornitore. Ci sono anche alcuni progetti che mirano a implementare interfacce in POSIX per Fortran 90: fortranposix e posix90. Ma come ho detto una corretta interfaccia C-Binding utilizzando le funzionalità di F2003 è probabilmente l'opzione più pulita, vedi anche lo fortranwiki.

Edit: Qui è il codice con la colla ISO-C-Binding aggiunto (testato con 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! Vedo il mio problema Sto passando gli argomenti usando la chiamata per riferimento così socket() non viene chiamato con le opzioni valide. Grazie! – hw12

0

Ecco un'ipotesi. Sei uno studente laureato in scienze o ingegneria (ma non in informatica o ingegneria informatica) e il tuo capo è nato prima del 1950. Se è così, mi sono messo nei tuoi panni (tranne che nel mio caso il requisito era usare Fortran 77) . Condivido il tuo dolore.

Come probabilmente saprete, Fortran non usa i file di intestazione per prototipare chiamate di funzioni nello stesso modo in cui lo fa C. È possibile chiamare una funzione Fortran senza l'intestazione, quando i tipi degli argomenti non vengono controllati.

Tuttavia, c'è questo problema - o un tempo c'era questo problema, perché la mia esperienza più recente è di parecchi anni non aggiornata. Rispetto a C, GNU Fortran antepone un underscore nascosto al nome di ogni funzione. Abbassa anche il nome della funzione.

Il programma readelf -a può aiutarti qui. Usalo sul file oggetto che il tuo compilatore Fortran emette. Cerca nell'output il simbolo socket. Se il mio ricordo è giusto, vedrai uno _socket lì dentro.

Se davvero, davvero non è possibile utilizzare alcun C - anche per fare una funzione wrapper con il nome C _socket() - quindi ammetto che non so cosa si dovrebbe fare dopo. In tal caso, potresti rimanere bloccato in un punto stretto. Ad ogni modo, buona fortuna.

Aggiornamento: Raccomando il commento di @ M.S.B. di seguito.

+6

È possibile assumere il controllo della denominazione delle funzioni con il binding ISO C descritto da haraldki ed evitare i caratteri di sottolineatura. Il mixaggio di Fortran e C è molto più semplice e più portatile di quanto non fosse in passato. –

+3

Sono nato nel 1982 e I is Fortran per nuovi progetti. Ho persino tradotto molto codice da C. Ho qualcosa di brutto con me? –

+0

@VladimirF: No, niente di male, ovviamente.Fortran è uno strumento per fare un lavoro e lo stai usando per fare il lavoro. Buon per te. Se vuoi sapere, la mia esperienza è stata il contrario. Mi fu chiesto di usare Fortran 77 (nemmeno il moderno Fortran) per scopi per i quali C o persino Perl erano più adatti. Non mi importava. Sono stato pagato, e non ho mai discusso con il mio capo al riguardo; ma, se mi chiedessi se penso che il mio capo abbia fatto la scelta giusta in questo caso, direi che non la penso così. Quanto a te: vai Fortran! – thb

Problemi correlati