Zum Inhalt springen

Fortran: Fortran und C: Fortran 90/95

Aus Wikibooks
<<< zur Fortran-Startseite
<< Fortran und C F >>
< Interface Fortran 2003 und C >


In Fortran 90/95 ist der Zugriff auf C-Funktionen nicht standardisiert. Derartige Zugriffe sind compilerabhängig zu lösen. Es sind je nach verwendetem Fortran-Compiler verschiedene Compilerdirektiven zu setzen, Optionen beim Compileraufruf und ähnliches zu beachten. Fortran 2003 bietet eine standardisierte Schnittstelle für den Zugriff auf C-Funktionen.

g95 (gfortran) und gcc

[Bearbeiten]

Beispiel: "call by value" und "call by reference"

[Bearbeiten]

Fortran übergibt die Argumente eines Unterprogrammes standardmäßig "call by reference". Im Zusammenspiel mit C besteht nun das Problem, dass in C Argumente "call by reference" via Pointer oder "call by value" übergeben werden . In g77, g95 und gfortran ist die Funktion %val inkludiert, mit der auch in Fortran der "call by value"-Mechanismus nachgebildet werden kann.

Fortran-Code bsp.f90:

Fortran 90/95-Code (free source form)
program bsp
  implicit none
 
  interface
    subroutine zahl(a, b)
      integer :: a, b
    end subroutine zahl
  end interface
 
  call zahl(%val(5), 7)
end program bsp 


C-Code bsp.c:

Programmcode
#include <stdio.h>
 
void zahl(int a, int *b)
{
  printf("%s%d\n", "Ergebnis = ", a * *b);
}


Compilieren und Linken:

gcc -c -o bsp1.o bsp.c
g95 -c -fno-underscoring -o bsp2.o bsp.f90 
g95 bsp1.o bsp2.o

Ausgabe:

Ergebnis = 35

Beispiel: Übergabe von Zeichenketten

[Bearbeiten]

In C sind Strings im Gegensatz zu Fortran Null-terminiert. Dies muss beim Aufruf einer C-Prozedur aus Fortran berücksichtigt werden.

Fortran Code bsp.f90:

Fortran 90/95-Code (free source form)
program bsp
  implicit none
 	 
  interface
    subroutine hallo(str)
      character(*) :: str
    end subroutine
  end interface
  
  call hallo("Hallo, Sonne" // char(0))        ! char(0) -> Nulltermination für C
  call hallo("Hallo, Protuberanz" // char(0))  ! char(0) -> Nulltermination für C
  call hallo("Hallo, Mond")                    ! keine Nulltermination
! Ausgabe:
!  Hallo, Sonne
!  Hallo, Protuberanz
!  Hallo, Mond ... More segments remain
end program bsp 


C-Code bsp.c:

Programmcode
#include <stdio.h>
 
void hallo(char *str)
{
  printf("%s\n", str);
}


Compilieren und Linken:

gcc -c -o bsp1.o bsp.c
g95 -c -fno-underscoring -o bsp2.o bsp.f90 
g95 bsp1.o bsp2.o

Beispiel: Rückgabewert

[Bearbeiten]

Die Rückgabe eines Wertes einfachen Datentyps aus einer C-Funktion nach Fortran stellt kein Problem dar. Es ist einzig zu beachten, dass der Datentyp in C und Fortran übereinstimmt.

Fortran-Code bsp.f90:

Fortran 90/95-Code (free source form)
program bsp
  implicit none
  
  interface
    function zahl(x, y)
      integer :: zahl
      integer :: x, y
    end function
  end interface
 
  integer :: res
  
  res = zahl(%val(76), %val(32))
  write(*,*) res
!  Ausgabe: 108	 
end program bsp 


C-Code bsp.c:

Programmcode
int zahl(int a, int b)
{
  return (a+b);
}

ifort und gcc

[Bearbeiten]

Beispiel: "call by value" und "call by reference"

[Bearbeiten]

Fortran-Code bsp.f90:

Fortran 90/95-Code (free source form)
program bsp
  implicit none
 
  interface
    subroutine zahl(a, b)
      !dec$ attributes c :: zahl
      !dec$ attributes reference :: b
      integer :: a, b
    end subroutine zahl
  end interface
 
  call zahl(5, 7)
end program bsp 


C-Code bsp.c:

Programmcode
#include <stdio.h>
 
void zahl(int a, int *b)
{
  printf("%s%d\n", "Ergebnis = ", a * *b);
}


Compilieren, Linken:

gcc -c -o bsp1.o bsp.c
ifort -c -o bsp2.o bsp.f90
ifort bsp1.o bsp2.o

Ausgabe:

Ergebnis = 35

Beispiel: Übergabe von Zeichenketten

[Bearbeiten]

Fortran-Code bsp.f90:

Fortran 90/95-Code (free source form)
program bsp
  implicit none
  
  interface
    subroutine hallo(str)
      !dec$ attributes c :: hallo
      !dec$ attributes reference :: str
      character(*) :: str
    end subroutine
  end interface
  
  call hallo("Hallo, Sonne" // char(0))  ! char(0) -> Nulltermination 
  call hallo("Hallo, Protuberanz"C)      ! C       -> Nulltermination (bei Intel-Fortran-Compiler) 
  call hallo("Hallo, Mond")              ! keine explizite Nullterminiation
! Ausgabe:
!  Hallo, Sonne
!  Hallo, Protuberanz
!  Hallo, Mond
end program bsp 


C-Code bsp.c:

Programmcode
#include <stdio.h>
 
void hallo(char *str)
{
  printf("%s\n", str);
}


Compilieren und Linken:

gcc -c -o bsp1.o bsp.c
ifort -c -o bsp2.o bsp.f90
ifort bsp1.o bsp2.o

Beispiel: Rückgabewert

[Bearbeiten]

Fortran-Code bsp.f90:

Fortran 90/95-Code (free source form)
program bsp
  implicit none
 	 
  interface
    function zahl(x, y)
      !dec$ attributes c :: zahl
      integer :: zahl
      integer :: x, y
    end function
  end interface
 
  integer :: res
  
  res = zahl(76, 32)
  write(*,*) res
!  Ausgabe: 108	 
end program bsp 


C-Code bsp.c:

Programmcode
int zahl(int a, int b)
{
  return (a+b);
}



<<< zur Fortran-Startseite
<< Fortran und C F >>
< Interface Fortran 2003 und C >