Skip to main content
⚠ INFORMATION
This page was translated by an AI (LLM) with a cursory human check and is awaiting full review.

Calling Fortran functions from C code

Some useful recommendations:

  1. The 2003 Fortran standard defined a way to interface Fortran procedures with functions written in C. This solution is recommended because it ensures portability and allows the linking of any Fortran type with those of the C language. For more information, refer to Chapter 9 of the Fortran Expert course: "Interoperability between C and Fortran entities";
  2. Parameter passing in Fortran is done by address, while in C it is done by value;
  3. It is recommended to link with the Fortran compiler. If it is the ifort compiler, the -nofor-main option is necessary to indicate that the main function is not a Fortran function.

Be aware that if you do not adopt the solution proposed by Fortran 2003, you will be subject to the following restrictions:

  1. When C activates a Fortran procedure, the arguments provided during the call must be addresses of basic type objects;
  2. During the compilation of the Fortran program, the -assume nounderscore option of the ifort compiler (-fno-underscoring if it is gfortran) must be specified so that it does not add the _ character when generating the external references corresponding to the calls made in C. Obviously, if this character is indicated as a suffix during these calls, this option should not be specified;
  3. As Fortran generates external references in lowercase, this must be respected when making calls in C.

Example of a C call

appelf.c
#include <stdio.h>
int main ()
{
int lg_chaine = 0;
float reel = 0.0;
char chaine[] = "chaîne_C";

lg_chaine = strlen(chaine);
concat( &lg_chaine, &reel, chaine);

printf("chaîne finale = %sn", chaine);
printf("longueur de la chaîne finale = %dn", lg_chaine);
printf("réel passé par adresse = %fn", reel);

return 0;
}

Example of definition in Fortran 2003/2008

concat.f90
module m
use ISO_C_BINDING, only : C_CHAR, C_INT, C_FLOAT
contains
SUBROUTINE concatenation( lg_chaine, reel, tab_car) bind(C,name='concat')
INTEGER(kind=C_INT) :: lg_chaine
REAL(kind=C_FLOAT) :: reel
CHARACTER(kind=C_CHAR), dimension(lg_chaine) :: tab_car
!
CHARACTER(kind=C_CHAR,len=lg_chaine) :: chaine
!write( chaine, '(*(a))' ) tab_car ! Format => Fortran 2008
! ou bien
do i=1,lg_chaine
chaine(i:i) = tab_car(i)
end do
!
chaine = TRIM(chaine)//' et chaîne_Fortran'
lg_chaine = LEN_TRIM(chaine)
reel = 100.0
END SUBROUTINE concatenation
end module m
# compilation
icc -c appelf.c
ifort -c concat.f90
ifort -nofor-main appelf.o concat.o -o appelf.exe
# execution
$ appelf.exe
chaîne finale = chaîne_C et chaîne_Fortran
longueur de la chaîne finale = 26
réel passé par adresse = 100.000000

Example of definition in Fortran 90/95

concat.f90
SUBROUTINE concat( lg_chaine, reel, chaine)
INTEGER, INTENT(INOUT) :: lg_chaine
REAL, INTENT(INOUT) :: reel
CHARACTER(LEN=lg_chaine), INTENT(INOUT) :: chaine
chaine = TRIM(chaine)//' et chaîne_Fortran'
lg_chaine = LEN_TRIM(chaine)
reel = 100.0
END SUBROUTINE concat
# compilation
icc -c appelf.c
ifort -c -assume nounderscore concat.f90
ifort -nofor-main appelf.o concat.o -o appelf.exe
# execution
$ appelf.exe
chaîne finale = chaîne_C et chaîne_Fortran
longueur de la chaîne finale = 26
réel passé par adresse = 100.000000

Your opinion matters!

To give your feedback, report an error, or suggest an improvement, click here:

quick anonymous questionnaire

This questionnaire is temporary and will take less than a minute, so take the opportunity!