-
Notifications
You must be signed in to change notification settings - Fork 16
Fortran iso_c_binding
gradcshou edited this page Oct 27, 2015
·
5 revisions
Work with C functions in Fortran using iso_c_binding module
Suppose we have a file test_iso_c_bind.c
containing three C functions:
#include <stdio.h>
void Basics (const double a, // in
const int n, // in
double *b) // out
{
// bala bala
}
void Array (const double c[], // in
double d[]) // out
{
// bala bala
}
double Function (double (*f) (double, void(*)), // a function pointer
void * g) // a pointer to some type
{
// bala bala
}
Now the question is how to call those 3 functions in a Fortran program. One of the most common solutions is to use Fortran iso_c_binding
module. Next, we'll demonstrate the way to use iso_c_binding
to achieve this.
- Basics
In this section, we'll show how to call Basics
function in a Fortran program test
.
program test
use iso_c_binding ! import iso_c_binding module
implicit none
!> Create an interface to C function
interface
subroutine Basics_c(a, n, b) bind(c, name='Basics')
use iso_c_binding, only :: c_int, c_double
real(kind=c_double), value, intent(in) :: a
integer(kind=c_int), value, intent(in) :: n
real(kind=c_double), intent(out) :: b
end subroutine Basics_c
end interface
!> Define C-type variables
real(kind=c_double) :: a_c, b_c
integer(kind=c_int) :: n_c
!> Define Fortran-type variable
real :: a_f, b_f
integer :: n_f
!> Assign values to a_f and n_f
a_f = 1.5
n_f = 1
!> Convert Fortran to C
a_c = real(a_f, kind=c_double)
n_c = integer(n_f, kind=c_int)
!> Call C function
call Basics(a_c, n_c, b_c)
!> Convert C output to Fortran type
b_f = real(b_c)
end program test
Remarks:
- An
interface
block is created to allowtest
program to accessBasics
function because we cannot import aC
program to aFortran
program usinguse
statement. - The
name
statement is used because subroutine nameBasics_c
is different from function nameBasics
. It can be omitted ifFortran
subroutine name is made to be the same as theC
function name. - The
only
statement specifies the only types required by declaringC
functionBasics
. This is economical way of loadingiso_c_binding
module. If we are lazy about this, we can simply douse iso_c_binding
withoutonly
statement. - The
value
attribute in the declaration ensures we are passing actual value of a variable, rather than its reference.C
program is by default "call-by-value" whereasFortran
program uses "call-by-reference" paradigm. - Because
b
in theBasics
function is declared to be a pointer (i.e. reference) todouble
, we don't supplyvalue
attribute. - Use
kind
statement to cast aFortran
data type to its correspondingC
type or vice versa. A complete list of interoperable data types betweenC
andFortran
can be found here.
-
Array as argument
-
Function as argument
-
References
- Interoperability with C (GNU): https://gcc.gnu.org/onlinedocs/gfortran/Interoperability-with-C.html