Sockets Programming Gfortran

sockets programming gfortran

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

Invoke a client-program written in C, from Fortran 90

Prior to the C interop facilities introduced in Fortran 2003, calling an external C function from Fortran required tricks specific to the target environment and the compilers involved. Moreover, if the C function in question was not designed specifically to be callable by code such as is generated by the Fortran compiler involved, then it was usually necessary to write a wrapper function (in C) to bridge the gap.

The main issues to be overcome are

  • name mangling: the name by which a function is referenced in Fortran source code often differs from the one the linker must link. Often one or more additional underscores are introduced, and typically the function name is put into a standard case (often lowercase, but some compilers have used uppercase).

  • argument types: some Fortran argument types simply cannot be passed cleanly, at least not without detailed knowledge of the relevant Fortran implementation. Assumed-shape arrays, array sections, and arrays with allocatable or pointer attributes are typically problematic.

  • representation of types: the biggest one here is array index order. Fortran arrays are indexed in column-major order, whereas C arrays are indexed in row-major order. This isn't necessarily a problem for passing arrays (but see also above); rather it presents a problem for using them correctly on one side and the other of the call. Another biggie here is that Fortran character objects (strings) are not null-terminated. Instead, each has a fixed length that is included in the value representation. This is usually accommodated at a C function interface by passing two actual arguments, a pointer to the start of the char array and a length, but other forms have been used as well.

  • function call semantics: Fortran passes all arguments by reference. That usually presents as a C function interface where the arguments are all pointers, with the exception that the string-length parameters described above (because Fortran character objects have fixed width).

  • argument order: a Fortran-callable C function will normally use the same argument order as it expects to be used by the Fortran-side call, but that's not guaranteed, and anyway the string-length arguments don't fit cleanly into that. Some Fortran compilers pass them immediately after the corresponding pointer; others group all the string length arguments at the end of the argument list. (And of course, that doesn't consider those that use an altogether different mechanism to represent string arguments.)

It's conceivable that I've overlooked something.

Pretty much all of that has substantial implementation dependencies, but people have nevertheless been calling back and forth between Fortran and C since well before Fortran 90 was conceived, and they continue to do it. If you do not have the benefit of standardized C interop to rely upon, then you need to know some details of how your Fortran compiler generates code. There are various automated facilities for that, including in GNU Autoconf, or you can just consult the docs or even experiment.

For what it's worth, you appear to have several problems, some in the areas described above, and some entirely in the Fortran part. Especially notable in the Fortran part is that you do not declare lengths for your character variables, so they all get the default length (1). That's evidently not what you want. At the function call, you are also being tripped up by Fortran not using null-terminated strings and by it passing extra arguments for the string lengths.

But Fortran 2003 is now thirteen years old, and the C interop bits are widely implemented, including in gfortran, which your Makefile reveals to be your Fortran implementation. The gfortran docs cover C interop fairly thoroughly. There is too much for this already-lengthy answer, but key points include:

  • Write the C part in natural C.
  • Use the ISO_C_BINDING module.
  • Write a Fortran interface to the C function, defining formal argument and return types appropriately, including with appropriate kind attributes (drawn from values provided as parameters by ISO_C_BINDING)
  • Apply the bind(C) attribute to symbols that must be interoperable with C

Using TCP for Inter Process Communication(IPC) with fortran

The problem is the different handling of strings in C and Fortran.

You pass "localhost" as a Fortran String, whose end is determined by a fixed (in this case implied) length. In C, strings have to end with a NUL. This can be achieved by writing

sockfd=ClientSocket("localhost"//C_NULL_CHAR, port)

where C_NULL_CHAR is defined in ISO_C_BINDING module.

GFortran equivalent of ieee_exceptions

GFortran supports the ieee_exceptions module as of the GCC 5 release.

If you're stuck on an older GFortran release, a workaround would be to implement functions in C/asm that get/set the FP trapping status register and call those from Fortran.

PS.: GFortran does have a switch (-fpe-trap) for globally enabling traps for FP exceptions, see http://gcc.gnu.org/onlinedocs/gfortran/Debugging-Options.html . But, since you explicitly said "no matter how it is compiled with gfortran", I guess you don't want to use that.



Related Topics



Leave a reply



Submit