Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sockets programming gfortran

I want to be able to call networking functions in my Fortran application. My boss wants me to do everything in Fortran instead of using C and Fortran. We have already done a version of the application using PGI's Fortran compiler on Windows. We are moving it to Linux where we will probably use their compiler. Right now, I'm using gfortran.

I have created an interface for these networking calls, and everything compiles and links. The code below is something similar to what I'm doing except the interfaces and constants are in a module.

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

When I run the program, the socket function fails returning -1. I don't really know what's going on. I don't add any libraries on the command line so I'm guess it is linking with the default libraries correctly. I compile using

gfortran -o MAIN_PROGRAM MAIN_PROGRAM.f90 -fno-underscoring
like image 583
hw12 Avatar asked Apr 24 '12 20:04

hw12


1 Answers

You can make use of the ISO_C_Binding introduced in Fortran 2003 to access C library functionality, this is the cleanest and most portable option you have. The Gfortran documentation has some details on it, as any other vendor manual. There are also some projects aiming to implement interfaces to POSIX for Fortran 90: fortranposix and posix90. But as I said a proper C-Binding interface using the F2003 capabilities is probably the cleanest option, see also the fortranwiki.

Edit: Here is your code with the ISO-C-Binding glue added (tested with 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
like image 129
haraldkl Avatar answered Sep 30 '22 02:09

haraldkl