8

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
M. S. B.
  • 28,968
  • 2
  • 46
  • 73
hw12
  • 83
  • 1
  • 4

2 Answers2

11

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
haraldkl
  • 3,809
  • 26
  • 44
  • 2
    Ah! I see my problem. I'm passing the arguments using call by reference so socket() is not being called with valid options. Thanks! – hw12 Apr 25 '12 at 13:02
0

Here's a guess. You're a graduate student in science or engineering (but not computer science or computer engineering) and your boss was born before 1950. If so, I have stood in your shoes (except that in my case the requirement was to use Fortran 77). I feel your pain.

As you probably know, Fortran does not use header files to prototype function calls in the same way C does. You can call a Fortran function without the header, when the types of the arguments are not checked.

However, there is this trouble -- or there used to be this trouble, for my most recent experience is several years out of date. Compared to C, GNU Fortran prepends a hidden underscore to the name of each function. It also lower-cases the function name.

The readelf -a program can help you here. Use it on the object file your Fortran compiler emits. Look in the output for the socket symbol. If my recollection is right, you'll see an _socket in there.

If you really, really cannot use any C at all -- even to make a wrapper function with the C name _socket() -- then I admit that I do not know what you should do next. In that case, you may be stuck in a tight spot. Either way, good luck.

Update: I recommend @M.S.B.'s comment below.

thb
  • 13,796
  • 3
  • 40
  • 68
  • 6
    You can take control of the naming of functions with the ISO C Binding described by haraldki and avoid the underscores. Mixing Fortran and C is much easier and more portable than it used to be. – M. S. B. Apr 24 '12 at 22:29
  • 4
    I was born 1982 and I ise Fortran for new projects. I even translated a lot of code from C. I something bad with me? – Vladimir F Героям слава Apr 25 '12 at 07:42
  • @VladimirF: No, nothing bad, of course. Fortran is a tool to do a job, and you're using it to do the job. Good for you. If you want to know, my experience was the reverse. I was required to use Fortran 77 (not even modern Fortran) for purposes for which C or even Perl was better suited. I didn't mind. I got paid, and I never argued with my boss about it; but, if you asked me whether I think that my boss made the right choice in this instance, I would say that I do not think so. As for you: go Fortran! – thb Apr 25 '12 at 15:27