<BIND Example Program 1>

!
! Demonstrates declaring and invoking a C procedure from Fortran.
!
Program bind_example_1
  Use Iso_C_Binding,Only:C_double
  Interface
    !
    ! This is for hypot from "libm".
    !
    Function hypotenuse(x,y) Bind(C,Name='hypot')
      Use Iso_C_Binding
      Real(C_double),Value :: x,y
      Real(C_double) :: hypotenuse
    End Function
  End Interface
  Print 1,0.3d0,0.4d0,hypotenuse(0.3_C_double,0.4_C_double)
1 Format(1X,'Hypotenuse for ',F0.2,',',F0.2,' is ',F0.2)
End

■ Execution Results

 Hypotenuse for .30,.40 is .50

<BIND Example Program 2>


! "ex2_fprog.f90"
! Demonstrates defining a procedure to be invoked from C.
!
! Fortran part.
!
Subroutine real_cshift_for_c(a,n,shift) Bind(C,Name='cshiftf')
  Use Iso_C_Binding
  Intrinsic Cshift
  Integer(C_int),Value :: n,shift
  Real(C_float),Intent(InOut) :: a(n)
  a = cshift(a,shift)
End Subroutine

/* "ex2_cprog.c"
 *
 * C part.
 */
#include <stdio.h>
extern void cshiftf(float *a,int n,int shift);

main()
{
  int i;
  float x[5] = { 1,2,3,4,5 };
  cshiftf(x,5,2);
  for (i=0; i<5; i++) printf(" %5.2f",x[i]);
  putc('\n',stdout);
  return 0;
}

■ Execution Results

 3.00  4.00  5.00  1.00  2.00

<BIND Example Program 3>


! "ex3_fprog.f90"
! Demonstrates BIND attribute on a variable.
! Also uses BIND attribute on procedures.
!
! Fortran part.
!
Module c_global_variables
  Use Iso_C_Binding
  Integer(C_long),Bind(C,Name='var1') :: x = 37_C_long
  Integer(C_short),Bind(C) :: y,z
  Interface
    Subroutine c_routine() Bind(C)
    End Subroutine
  End Interface
End Module
Program bind_example_3
  Use c_global_variables
  Call c_routine
  Print *,x,y,z
End Program

/* "ex3_cprog.c"
 *
 * C part.
 */
extern long var1;
short y = 10, z = 0;

void c_routine(void)
{
  z = var1 + 1;
}

■ Execution Results

 37 10 38

<BIND Example Program 3>

! "ex4_fprog.f90"
! Demonstrates BIND attribute on a derived type,
! Also uses BIND attribute on procedures.
!
! Fortran part.
!
Module c_struct_defn
  Use Iso_C_Binding
  Type,Bind(C) :: mystruct
    Real(C_float) :: x,y
    Integer(C_int) :: flags(100,200)
    Type(C_ptr) :: name  ! This is actually a char *.
    Type(C_ptr) :: z     ! This is actually a float *.
    Type(C_funptr) :: callback
  End Type
  Interface
    Subroutine init_mystruct(newvar) Bind(C)
      Import mystruct
      Type(mystruct),Intent(Out) :: newvar
    End Subroutine
    Subroutine process_mystruct(var) Bind(C)
      Import mystruct
      Type(mystruct),Value :: var
    End Subroutine
  End Interface
End Module
Program bind_example_4
  Use c_struct_defn
  Type(mystruct) x
  Call init_mystruct(x)
  x%x = 100
  x%y = 140
  Call process_mystruct(x)
End Program

/* "ex4_cprog.c"
 *
 * C part.
 */
#include <stdio.h>

struct mystruct {
  float x,y;
  int flags[200][100];
  char *name;
  float *z;
  void (*callback)(struct mystruct *);
};

void print_my_name(struct mystruct *object)
{
  fputs(object->name,stdout);
}

void init_mystruct(struct mystruct *newvar)
{
  int i,j;
  newvar->x = 0;
  newvar->y = 0;
  for (i=0; i<200; i++) for (j=0; j<100; j++) newvar->flags[i][j] = 0;
  newvar->name = "No name yet";
  newvar->z = (float *)0;
  newvar->callback = &print_my_name;
}

void process_mystruct(struct mystruct var)
{
  int i,j;
  printf("mystruct processing: %f, %f\n",var.x,var.y);
  for (i=0; i<200; i++) for (j=0; j<100; j++) if (var.flags[i][j])
    printf("  flags[%d][%d]==0x%x\n",i,j,var.flags[i][j]);
  if (var.callback) var.callback(&var);
}

■ Execution Results

 mystruct processing: 100.000000, 140.000000
 No name yet