2012-04-24 10 views
6

Quiero poder llamar funciones de red en mi aplicación Fortran. Mi jefe quiere que haga todo en Fortran en lugar de usar C y Fortran. Ya hemos hecho una versión de la aplicación usando el compilador Fortran de PGI en Windows. Lo estamos trasladando a Linux, donde probablemente utilicemos su compilador. En este momento, estoy usando gfortran.sockets que programan gfortran

He creado una interfaz para estas llamadas de red, y todo compila y enlaces. El siguiente código es similar a lo que estoy haciendo, excepto que las interfaces y las constantes están en un módulo.

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 

Cuando ejecuto el programa, la función de socket falla al devolver -1. Realmente no sé lo que está pasando. No agrego ninguna biblioteca en la línea de comandos, así que supongo que está enlazando con las bibliotecas predeterminadas correctamente. Compilo usando

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

¿Has probado para comprobar errno? –

Respuesta

8

Puede utilizar el enlace ISO_C_Binding introducido en Fortran 2003 para acceder a la funcionalidad de la biblioteca C, esta es la opción más limpia y portátil que tiene. El Gfortran documentation tiene algunos detalles, como cualquier otro manual del vendedor. También hay algunos proyectos que apuntan a implementar interfaces a POSIX para Fortran 90: fortranposix y posix90. Pero como dije, una interfaz C-Binding adecuada usando las capacidades F2003 es probablemente la opción más limpia, vea también el fortranwiki.

Editar: Aquí está el código con el pegamento ISO-C-Binding añadido (probado 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! Veo mi problema Paso los argumentos usando llamada por referencia para que socket() no se llame con opciones válidas. ¡Gracias! – hw12

0

Aquí hay una conjetura. Eres un estudiante graduado en ciencias o ingeniería (pero no en informática o ingeniería informática) y tu jefe nació antes de 1950. Si es así, he estado en tu lugar (excepto que en mi caso el requisito era usar Fortran 77) . Siento tu dolor.

Como probablemente sepa, Fortran no utiliza los archivos de encabezado para crear prototipos de llamadas de funciones de la misma manera que C. Puede llamar a una función Fortran sin el encabezado, cuando los tipos de argumentos no están marcados.

Sin embargo, existe este problema, o solía haber este problema, ya que mi experiencia más reciente es varios años desactualizada. Comparado con C, GNU Fortran antepone un guion bajo al nombre de cada función. También minimiza el nombre de la función.

El programa readelf -a puede ayudarlo aquí. Úselo en el archivo objeto que emite su compilador Fortran. Mire en la salida para el símbolo socket. Si mi recuerdo es correcto, verá un _socket allí.

Si realmente, realmente no puede usar ninguna C en absoluto, incluso para hacer una función de contenedor con el nombre de C _socket(), entonces admito que no sé qué debe hacer a continuación. En ese caso, puedes quedarte atrapado en un aprieto. De cualquier manera, buena suerte.

Actualización: Recomiendo el comentario de @ M.S.B. a continuación.

+6

Puede tomar el control de la denominación de funciones con el enlace ISO C descrito por haraldki y evitar los guiones bajos. Mezclar Fortran y C es mucho más fácil y más portátil de lo que solía ser. –

+3

Nací en 1982 y estoy en Fortran para nuevos proyectos. Incluso traduje un montón de código de C. ¿Hay algo malo conmigo? –

+0

@VladimirF: No, nada malo, por supuesto.Fortran es una herramienta para hacer un trabajo, y lo estás usando para hacer el trabajo. Bien por usted. Si quieres saber, mi experiencia fue al revés. Debía usar Fortran 77 (ni siquiera el Fortran moderno) para fines para los cuales C o incluso Perl eran más adecuados. No me importó. Me pagaron, y nunca discutí con mi jefe al respecto; pero, si me preguntas si creo que mi jefe tomó la decisión correcta en este caso, diría que no lo creo. En cuanto a ti: ¡vete a Fortran! – thb