Gfortran socket programming

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

I created an interface for these network calls, and everything compiles and links. Below is code similar to what I am doing, except that the interfaces and constants are in the 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 does not return -1. I do not know what's going on. I do not add any libraries on the command line, so I assume that it links correctly with the default libraries. I compile with

 gfortran -o MAIN_PROGRAM MAIN_PROGRAM.f90 -fno-underscoring 
+6
source share
2 answers

You can use the ISO_C_Binding implemented in Fortran 2003 to access the functions of the C library, which is the cleanest and most portable option you have. The Gfortran documentation contains some information about this, like any other sales manual. There are also projects aimed at implementing POSIX interfaces for Fortran 90: fortranposix and posix90 . But, as I said, a suitable C-Binding interface using the capabilities of F2003 is probably the cleanest option, see also fortranwiki .

Edit: Here is your code with the addition of ISO-C-Binding glue (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 
+8
source

Here is a hunch. You are a graduate student in science or technology (but not computer science or computer engineering), and your boss was born before 1950. If so, I stood on your shoes (except that in my case it was necessary to use Fortran 77), I feel your pain.

As you probably know, Fortran does not use header files for prototyping function calls in the same way as C. You can call a Fortran function without a header if the argument types are not marked.

However, there is this problem - or once there was this problem, since my most recent experience is an outdated year. Compared to C, GNU Fortran adds hidden underscore to the name of each function. It also shortens the name of the function.

The readelf -a program can help you here. Use it in the object file that the Fortran compiler emits. Look at the output for the socket symbol. If my memory is correct, you will see _socket there.

If you really really can't use any C at all - even to create a wrapper function called C _socket() , then I admit that I don't know what you should do next. In this case, you may be stuck in a bottleneck. In any case, good luck.

Update: I recommend @MSB comment below.

0
source

Source: https://habr.com/ru/post/914074/


All Articles